假的三首杀。因为交文件所以他们都不往OJ上交。

假装是三首杀吧。嗯。

然而昨天还是没有AK。好像说是按照64位评测机的评测结果为准。

但是联赛省选的机子好像都是32位的?也就是和我们正在用的一致。

所以代码放在联赛上也能过,没锅就行,天灾人祸丢了40分那就没办法了。

关键是在自己的机子上怎么测都能过,而且还不能模拟评测机环境,昨天我在本机测了一组最大数据才交的。

因为64位机在递归的时候int的栈空间是按照8bit算的(强制开long long??),所以我就爆栈了。

(200000深度的dfs我申请了7个int,大约是5.3MB,而评测机按8位算之后变成了10.6MB)

但是不管怎么说也是涨了个记性,在题目没有说明无限栈的情况下栈空间就是8MB,不要炸。

(虽说平时自己机子上跑出来了就没什么问题。据说今天就是按照32位评测机的结果为准的)

(尚无定论,我还是不瞎说了,实在不行以后就按照4MB算)

回到今天。所以今天才是自己这辈子第一次AK非B组题,也是第一次三首杀AK。

昨天白高兴了。。。rank5还在讲题的时候上去说了半天现在想想十分尴尬。。。

但是这两天的题都比较合我的胃口。而且这次很没水准。

T1打表找规律。T2复杂版原题。T3算是自己想出来的(其实不是特别难想所以没什么可开心的)。

没有大数据结构,部分分给的很全而且还有提示意义,思考量也刚好合适。

所以做的顺手了分就上去了。这两天还在写对拍所以没出什么意外(呃。。。在能力范围内没什么意外。。。64位就算了)

我还是希望如果遇到不顺手的题也能像这样稳住心态不断的思考尽力的拿分保分吧。。。

T1:简单计算

打表找规律得到的式子(我爱打表找规律)

懒得写Latex了,不粘题面粘题解应该没什么事吧(不然其实也就是抄一遍)

打表找规律不乏是一个考场上的好技巧啊2333

1 #include<cstdio>
2 int gcd(int a,int b){return b?gcd(b,a%b):a;}
3 int main(){freopen("simplecalc.in","r",stdin);freopen("simplecalc.out","w",stdout);
4     int t,p,q,g;scanf("%d",&t);
5     while(t--)scanf("%d%d",&p,&q),g=gcd(p,q),printf("%lld\n",(p+1ll)*q/2-(p-1)/2+(g-1)/2);
6 }
呃。。。6行

T2:格式化

如果只有收益,那么当然按照格式化之前的容量从小到大挨个来。

如果只有亏损,那么当然按照格式化之后的容量从大到小挨个来。(完全反过程,和B组原题一样)

如果有收益有亏损,那么肯定先收益后亏损。

是一个比较普通也不是很不可证的贪心。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 struct P{int lim,E;}A[1000005],B[1000005];
 5 bool comA(P x,P y){return x.lim<y.lim;}
 6 bool comB(P x,P y){return x.E>y.E;}
 7 long long res,ans;int n,cA,cB;
 8 int main(){
 9     freopen("reformat.in","r",stdin);
10     freopen("reformat.out","w",stdout);
11     scanf("%d",&n);
12     for(int i=1,od,nw;i<=n;++i){
13         scanf("%d%d",&od,&nw);
14         if(nw>=od)A[++cA]=(P){od,nw};
15         else B[++cB]=(P){od,nw};
16     }
17     sort(A+1,A+1+cA,comA);
18     for(int i=1;i<=cA;++i)
19         if(res<A[i].lim)ans+=A[i].lim-res,res=A[i].E;
20         else res+=A[i].E-A[i].lim;
21     sort(B+1,B+1+cB,comB);
22     for(int i=1;i<=cB;++i)
23         if(res<B[i].lim)ans+=B[i].lim-res,res=B[i].E;
24         else res+=B[i].E-B[i].lim;
25     printf("%lld\n",ans);
26 }
View Code

T3:真相

暂且把第一种类型的人称为“预言家”吧。

如果没有预言家,那么可以O(n)爆扫。(枚举第一个人的真假,然后递推到第n个人看是否矛盾)

如果有预言家,那么可以先枚举某一个预言家为真,然后其它所有人都可以递推得到。

(其它预言家的k值如果与你判定为真的预言家不同那么必定为假,其余预言家为真,其他人可以根据顺时针下一个人推出)

(也就是,每个语言家直接决定了向前一直走到上一个预言家的位置这一段区间内所有人的真假状态)

还要考虑所有预言家都是假的情况,这样的话也是可以线性递推的,不过最后要看一下得到的说真话的人数不能与任何一个预言家所说的一致。

到这里就是$O(n^2)$的了。

可以发现一个问题,每一次你枚举不同的预言家为真时,除了这两个预言家外剩下预言家所控制的区间其实都没有变化。

我们对所有预言家都为假时的总共的说真话人数求和,再把k值相同的预言家压成一个。

每次考虑一个k值时,从你的求和值里减去这类预言家的贡献,再加上这个预言家说真话的贡献。

(然而我枚举的不是k值,而是所有k值不同的预言家)

判断此时说真话的人数是否符合即可。

再说一遍不要忘了所有预言家都是假的的情况。

还要注意,这题没有给出对k值的限制,所以直接枚举k值可能是错误的。

实际上数据里满足$0 \leq k \leq n$,但是还是有人跪在了$k=0$的情况上。

考场上我也不知道k的范围所以我是枚举的所有预言家的k值,这样的话会更严谨一些。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int opt[100005],k[100005],n,spj,pcnt,re[100005],consistent,inconsistent;
 4 int r(int p){return p>n?1:p;}
 5 struct P{
 6     int K,t,f,u;
 7     friend bool operator<(P a,P b){
 8         return a.K<b.K;
 9     }
10 }p[100005];
11 bool chk(){
12     re[1]=1;
13     for(int i=2;i<=n;++i)re[i]=re[i-1]^opt[i-1];
14     if(re[1]==(re[n]^opt[n]))return true;
15     re[1]=0;
16     for(int i=2;i<=n;++i)re[i]=re[i-1]^opt[i-1];
17     if(re[1]==(re[n]^opt[n]))return true;
18     return false;
19 }
20 main(){
21     freopen("truth.in","r",stdin);
22     freopen("truth.out","w",stdout);
23     int t;char s[3];
24     scanf("%d",&t);
25     while(t--){
26         scanf("%d",&n);spj=pcnt=consistent=inconsistent=0;
27         for(int i=1;i<=n;++i){
28             scanf("%s",s);
29             if(s[0]=='$')scanf("%d",&k[i]),opt[i]=-1,spj=1;
30             else if(s[0]=='+')opt[i]=0;
31             else opt[i]=1;
32         }
33         if(!spj){puts(chk()?"consistent":"inconsistent");continue;}
34         for(int i=1;i<=n;++i)if(opt[i]==-1){
35             int j=i-1;if(!j)j=n;re[i]=1;
36             p[++pcnt]=(P){k[i],1,0,0};
37             while(opt[j]!=-1){
38                 re[j]=re[r(j+1)]^opt[j];
39                 if(re[j])p[pcnt].t++;else p[pcnt].f++;
40                 j--;if(!j)j=n;
41             }
42         }
43         sort(p+1,p+1+pcnt);
44         int lst=0;p[0].K=-20030208;
45         for(int i=1;i<=pcnt;++i)
46             if(p[i].K==p[lst].K)p[lst].t+=p[i].t,p[lst].f+=p[i].f,p[i].u=1;
47             else lst=i;
48         int totf=0;
49         for(int i=1;i<=pcnt;++i)if(!p[i].u)totf+=p[i].f;
50         for(int i=1;i<=pcnt;++i)if(!p[i].u)if(p[i].K==totf-p[i].f+p[i].t)consistent=1;
51         for(int i=1;i<=pcnt;++i)if(p[i].K==totf)inconsistent=1;
52         puts((consistent||!inconsistent)?"consistent":"inconsistent");
53     }
54 }
View Code
12-29 08:29