CFGym 100198C (Strange Counter)
题意:定义一个新的二进制表达式,即在原来基础上把最大权值修改为2。其次,我们每加一个2^k保证改变数字不超过4次。给定最长数字长度,现在你需模拟这个过程。
思路:不超过4次,说明我们需要维护这个数字列连续为2的不超过3(高位除外),怎么制定策略呢?,我们可以制定这样的策略:保证两个2之间至少有一个0,因为只有这样,才能在4步内维护这样的结构。我们记录每个2和0的位置,那我们位置p填加时总是保证每个2间有个0。一直维护即可,具体做法参考代码吧。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e4 + 5; 4 5 int b[maxn]; 6 set<int> p0, p2; 7 set<int>::iterator it, it1; 8 9 void update(int p,int val) { 10 if(b[p]==0) p0.erase(p); 11 if(b[p]==2) p2.erase(p); 12 b[p] += val; 13 printf(" %d %d", p, b[p]); 14 if(b[p]==0) p0.insert(p); 15 if(b[p]==2) p2.insert(p); 16 } 17 18 int main() { 19 freopen("counter.in","r",stdin); 20 freopen("counter.out","w",stdout); 21 int n, m; 22 cin >> n >> m; 23 memset(b,0,sizeof(b)); 24 p0.clear(); 25 p2.clear(); 26 for(int i=0;i<n+5;i++) 27 b[i]=0, p0.insert(i); 28 p2.insert(maxn);//记住用upper_bound一定要添加一个不会出现的最大数,否则返回值很诡异 29 while(m--) { 30 int x; 31 scanf("%d", &x); 32 it = p2.upper_bound(x); //位置x后出现的第一个2 的位置 33 it1 = p0.upper_bound(*it); 34 it1 --;// 2前面第一个0的位置 35 if(x >= *it1) { 36 printf("3");//完全可预估我们所要花的步数 37 update(*it, -2); 38 update(*it+1, 1); 39 update(x, 1); 40 puts(""); 41 } else if(b[x]>0) { 42 printf("2"); 43 update(x, -1); 44 update(x+1, 1); 45 puts(""); 46 } else { 47 printf("1"); 48 update(x, 1); 49 puts(""); 50 } 51 } 52 return 0; 53 }