B.Light bulbs(差分)
题意:
T组案例,每组案例:n个灯泡( 0 ---- n-1),初始所有灯泡为熄灭状态,m次操作,每次操作把区间[L,R]内的灯泡翻转(开变关,关变开),问m次操作之后有多少灯泡是亮着的。
题解:
每次操作对[L,R]的所有数进行+1操作,求最后有多少个奇数。(设该数组为a[n],每次操作a[L]+1,a[R+1]-1,求前缀和sum[i]=sum[i-1]+a[i]即可得到进行区间所有数+1操作后每个数的值sum[i])
方法一:差分,
#include<bits/stdc++.h>
using namespace std;
const int maxn=2005;
pair<int,int>p[maxn];
int main(){
int T,cas = 1;
scanf("%d",&T);
while(T--){
int n, m, l, r, cnt=0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++){
scanf("%d%d", &l, &r);
p[cnt++] = make_pair(l,1);
p[cnt++] = make_pair(r+1,-1);
}
sort(p, p+cnt);
int sum = 0, ans = 0;
for(int i = 1; i < cnt; i++){
sum += p[i].second;
if(sum & 1){
ans += p[i].first - p[i-1].first;
}
}
printf("Case #%d: %d\n", cas, ans);
cas++;
}
return 0;
}
方法二:区间,优先队列
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e6 + 5;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
int sum[maxn];
struct node{
int l;
int r;
bool operator < (const node& e) const
{
if(l == e.l) return r > e.r;
return l > e.l;
}
};
priority_queue<node>pq;
int main(){
int T;
scanf("%d", &T);
for(int cas = 1; cas <= T; cas++){
int n, m;
while(!pq.empty()) pq.pop();
scanf("%d%d", &n, &m);
for(int i = 0; i < m; i++){
int l, r;
scanf("%d%d", &l, &r);
node e; e.l = l; e.r = r;
pq.push(e);
}
ll ans = 0;
while(pq.size() > 1){
node e = pq.top(); pq.pop();
node e2 = pq.top(); pq.pop();
if(e.r == e2.r && e.l == e2.l) continue;
else if(e.r < e2.l){
ans += (e.r - e.l + 1) * 1ll;
node tmp; tmp.l = e2.l; tmp.r = e2.r;
pq.push(tmp);
}
else if(e.l <= e2.l && e2.r < e.r){
ans += (e2.l - e.l) * 1ll;
node tmp; tmp.l = e2.r + 1; tmp.r = e.r;
if(tmp.l <= tmp.r) pq.push(tmp);
}
else{
ans += (e2.l - e.l) * 1ll;
node tmp; tmp.l = e.r + 1; tmp.r = e2.r;
pq.push(tmp);
}
}
if(pq.size() > 0) ans += pq.top().r - pq.top().l + 1;
printf("Case #%d: %lld\n", cas, ans);
}
return 0;
}
L.Digit sum
题意:
给出n和b,求1到n,各数在b进制下各位数之和的总和。
题解:
模拟打表
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+10;
int ans[11][maxn];
int fun(int n, int m){
int res = 0;
while(n){
res += n % m;
n /= m;
}
return res;
}
int main(){
for(int i = 2; i <= 10; i++){
ans[i][1] = 1;
}
for(int i = 2; i <= 10; i++){
for(int j = 2; j <= 1000000; j++){
ans[i][j] = ans[i][j-1] + fun(j, i);
}
}
int t;
scanf("%d", &t);
for(int x = 1; x <= t; x++){
int n, m;
scanf("%d%d", &n, &m);
printf("Case #%d: %d\n", x, ans[m][n]);
}
return 0;
}