CodeForces - 818D Multicolored Cars(思维)
2017-09-07 11:45
423 查看
题目大意:
首先,给你一个数列1e6,并给定你一个数字A,然后让你选出一个数字B,满足,对于数列中任意一个位置,该位置之前出现的A的个数不大于B出现的次数。
分析:
首先,我用一个跳跃数组a[i]来表示值i是否可能是答案。这里我说的跳跃数组就是,对于数组的某一个位置,我可以直接跳到它的下一个位置或者上一个位置,这样我就可以在删除其中的若干元素之后在下一次遍历的时候,不遍历这些被删除的元素。然后我就按照所给数列出现的顺序一个一个的添加到计数数组num中去,遇到数字A,我就遍历一遍跳跃数组并删除所需删除的元素。下面分析一下这个办法的时间复杂度:
首先,出现一个数字A,就会遍历一次跳跃数组,那么,A第i次出现的时候,跳跃数组需要遍历的位置最多只需要n/i次。那么总的遍历次数就是n×(1+12 +13 +14 +。。+1m ) ,m为A出现的次数,那么这个值最大就是n×(1+12 +13 +。。。+1n ) 。当n取1e6的时候,我用代码算了一下,是1.43927×1e7,这个复杂度应该是可以过的。后续:
然后看了下别人的代码,好像我就是想麻烦了。只要用p和sum分别记录当前可以选择的最大值和最大值出现的次数,然后随着输入新的数,不断地更新这个信息就好了。同时记录每个数出现的次数。这样当一个数添加的时候,如果他之前出现的次数小于之前A出现的次数,那么我就不记录他的这次出现了,那么他就相当于永远不能超过A出现的次数了。这样一次遍历O(n)的时间就完成了解答。代码:
#include<bits/stdc++.h> using namespace std; #define maxn 1000500 #define maxe 1000000 struct node { bool can;//是否可能为答案 int next;//下一个可能为答案的位置标号 int last;//上一个可能为答案的位置标号 }a[maxn]; int n,A,temp,first,appear_num[maxn],A_num; void init() { first=1;A_num=0; for(int i=0;i<maxn;i++) { a[i].can=1; a[i].next=i+1; a[i].last=i-1; } } void del(int x) { a[x].can=0; if(a[x].last!=-1)a[a[x].last].next=a[x].next; if(a[x].next<=maxe)a[a[x].next].last=a[x].last; if(x==first) { first=a[x].next; } } int main() { scanf("%d%d",&n,&A); init(); del(A); for(int i=0;i<n;i++) { scanf("%d",&temp); if(temp!=A) { if(a[temp].can==0)continue; appear_num[temp]++; } else { if(first>maxe)continue; int t=first; A_num++; while(t<=maxe) { if(appear_num[t]<A_num) { del(t); } t=a[t].next; } } } //cout<<first; printf("%d",(first>maxe)?-1:first); }
相关文章推荐
- Codeforces 156 A——Message——————【思维题】
- Codeforces 320E Kalila and Dimna in the Logging Industry【思维+贪心+斜率优化Dp】好题!
- Codeforces 406B Toy Sum【思维】
- CodeForces 55D. Beautiful numbers (思维+数位DP)
- Codeforces 492D Vanya and Computer Game【模拟+循环节+思维】好题~
- CodeForces - 831C Jury Marks (set思维)
- Codeforces 239E World Eater Brothers【思维+树形Dp】
- CodeForces 354A - Vasya and Robot (简单思维)
- Codeforces 798C Mike and gcd problem【思维+贪心】好题!
- CodeForces 604C 【思维水题】`
- 【CodeForces】222A - Shooshuns and Sequence(思维)
- 【CodeForces 804B】Minimum number of steps(思维+数学)
- Codeforces 149C Division into Teams 【思维】
- CodeForces 604C Alternative Thinking(思维题)
- Codeforces 527C Glass Carving【思维+模拟】
- ★codeforces 612D The Union of k-Segments (思维or类扫描线)
- codeforces 673C(思维)
- CodeForces 808A——Lucky Year——思维,模拟
- codeforces-141【B找规律】【C思维】
- 【Codeforces】-699A-Launch of Collider(思维)