[考试反思]0929csp-s模拟测试55:消逝

菜得过分。

面对T1的大板子不知所措,然后T2的贪心不小心把排序语句删了。。。

T1这种大模板啊。。。其实我是觉得我能打出来的,然后先用一个小时码了一个2k。

然后做T2想贪心就出来了。十分钟码完T3暴力之后回T1打对拍瞬间爆炸。

于是又重新打了一个2k,WA0。对拍发现。

然后考试就没几分钟了交暴力走了。

不要打完就跑,记得早点对拍改进思路。

 

T1:联

的确是挺裸的线段树。离散化或者权值线段树都可以。

但是考场上两个都打出来都死了。

最后用离散化A的。

 1 #include<cstdio>
 2 #include<unordered_map>
 3 #include<algorithm>
 4 using namespace std;
 5 #define inf 10000001
 6 unordered_map<long long,int>M;
 7 int m,cnt,k[100005];long long x[300005],l[100005],r[100005],re[300005];
 8 struct Segment_Tree{
 9     int cl[1500005],cr[1500005],lz[1500008],lzxor[1500008],w0[1500008],w1[1500008];
10     void build(int p,int l,int r){
11         cl[p]=l;cr[p]=r;lz[p]=-1;w0[p]=l;w1[p]=inf;
12         if(l==r)return;
13         build(p<<1,l,l+r>>1);build(p<<1|1,(l+r>>1)+1,r);
14     }
15     void up(int p){w0[p]=min(w0[p<<1],w0[p<<1|1]);w1[p]=min(w1[p<<1],w1[p<<1|1]);}
16     void down(int p){
17         if(lz[p]!=-1){
18             lz[p<<1]=lz[p],lz[p<<1|1]=lz[p];
19             lzxor[p<<1]=lzxor[p<<1|1]=0;
20             if(lz[p])w1[p<<1]=cl[p<<1],w1[p<<1|1]=cl[p<<1|1],w0[p<<1]=w0[p<<1|1]=inf;
21             else w1[p<<1]=w1[p<<1|1]=inf,w0[p<<1]=cl[p<<1],w0[p<<1|1]=cl[p<<1|1];
22             lz[p]=-1;
23         }else if(lzxor[p]){
24             if(lz[p<<1]!=-1)lz[p<<1]^=1;else lzxor[p<<1]^=1;
25             if(lz[p<<1|1]!=-1)lz[p<<1|1]^=1;else lzxor[p<<1|1]^=1;
26             swap(w1[p<<1],w0[p<<1]);
27             swap(w1[p<<1|1],w0[p<<1|1]);
28             lzxor[p]=0;
29         }
30         up(p);
31     }
32     void set(int p,int l,int r,int w){
33         if(l<=cl[p]&&cr[p]<=r){
34             lz[p]=w;lzxor[p]=0;
35             if(w)w1[p]=cl[p],w0[p]=inf;
36             else w1[p]=inf,w0[p]=cl[p];
37             return;
38         }
39         down(p);
40         if(l<=cr[p<<1])set(p<<1,l,r,w);
41         if(r>=cl[p<<1|1])set(p<<1|1,l,r,w);
42         up(p);
43     }
44     void Xor(int p,int l,int r){
45         if(l<=cl[p]&&cr[p]<=r){
46             if(lz[p]!=-1)lz[p]^=1;else lzxor[p]^=1;
47             swap(w0[p],w1[p]);
48             return;
49         }
50         down(p);
51         if(l<=cr[p<<1])Xor(p<<1,l,r);
52         if(r>=cl[p<<1|1])Xor(p<<1|1,l,r);
53         up(p);
54     }
55 }Tree;
56 main(){
57     scanf("%d",&m);
58     for(int i=1;i<=m;++i)scanf("%d%lld%lld",&k[i],&l[i],&r[i]),x[i]=l[i],x[m+i]=r[i],x[m+m+i]=r[i]+1;
59     sort(x+1,x+1+m+m+m);
60     for(int i=1;i<=m*3;++i)if(x[i]!=x[i-1])M[x[i]]=++cnt,re[cnt]=x[i];
61     for(int i=1;i<=m;++i)l[i]=M[l[i]],r[i]=M[r[i]];
62     if(M.find(1)==M.end()){for(int i=1;i<=m;++i)puts("1");return 0;}
63     Tree.build(1,1,cnt);Tree.lz[1]=0;
64     for(int i=1;i<=m;++i){
65         if(k[i]==1)Tree.set(1,l[i],r[i],1);
66         if(k[i]==2)Tree.set(1,l[i],r[i],0);
67         if(k[i]==3)Tree.Xor(1,l[i],r[i]);
68         printf("%lld\n",re[Tree.w0[1]]);
69     }
70 }
View Code

思路积累:

  • 线段树模板

 

T2:赛

三分其实不完全正确。虽然secret证明了单峰性质,但是ooo给出了函数值在谷底以外的地方不严格单调的例子。

直接贪心的话我们会发现决策有点复杂而且还可能会反悔。

但是其实只有四种物品,它们内部先排一下序(一定要排序啊啊啊)

根据数据范围的提示,两人都喜欢的物品是特殊的。

然后如果我们确定了两人都喜欢的物品的选择数量,剩下的贪心决策就好说了。

总费用关于它是个单峰函数(非严格)。

注意左右端点。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 struct ps{
 5     int c1,c2;long long v;
 6     friend bool operator<(ps a,ps b){return a.v<b.v;}
 7 }p[100005];
 8 int n,m,k,a,b,n0,n1,n2,n3;long long v[100005],c1[100005],c2[100005];
 9 long long q0[100005],q1[100005],q2[100005],q3[100005],ans=100000000000000000ll;
10 long long chk(int p){
11     long long tot=0,lft=m-k-(k-p);
12     for(int i=1;i<=p;++i)tot+=q3[i];
13     for(int j=1;j<=k-p;++j)tot+=q1[j]+q2[j];
14     int p0=1,p1=k-p+1,p2=k-p+1;
15     while(lft--)
16         if(q0[p0]<q1[p1]&&q0[p0]<q2[p2])tot+=q0[p0],p0++;
17         else if(q1[p1]<q2[p2])tot+=q1[p1],p1++;
18         else tot+=q2[p2],p2++;
19     ans=min(ans,tot);//printf("%d %lld\n",p,tot);
20     return tot;
21 }
22 main(){
23     scanf("%d%d%d",&n,&m,&k);
24     for(int i=1;i<=n;++i)scanf("%lld",&v[i]);
25     scanf("%d",&a);for(int i=1,x;i<=a;++i)scanf("%d",&x),c1[x]=1;
26     scanf("%d",&b);for(int i=1,x;i<=b;++i)scanf("%d",&x),c2[x]=1;
27     for(int i=1;i<=n;++i)
28         if(c1[i]&&c2[i])q3[++n3]=v[i];
29         else if(c1[i])q1[++n1]=v[i];
30         else if(c2[i])q2[++n2]=v[i];
31         else q0[++n0]=v[i];
32     sort(q0+1,q0+n0+1);
33     sort(q1+1,q1+n1+1);
34     sort(q2+1,q2+n2+1);
35     sort(q3+1,q3+n3+1);
36     q0[n0+1]=q1[n1+1]=q2[n2+1]=1000000000000ll;
37     int l=0,r=n3;
38     l=max(l,max(k-n1,k-n2));l=max(l,2*k-m);//printf("%d %d\n",l,r);
39     if(l>r){puts("-1");return 0;}
40     while(l<r-1)if(chk(l+r>>1)<chk((l+r>>1)+1))r=l+r>>1;else l=l+r>>1;
41     for(int i=l;i<=r;++i)chk(i);
42     printf("%lld\n",ans);
43 }
View Code
  • 贪心
  • 单峰函数三分
  • 这两个知识点总在一起出现?

 

T3:题

见下发题解。

挺神仙的。

 1 #include<cstdio>
 2 #include<bitset>
 3 using namespace std;
 4 bitset<401>B[401];
 5 int n,m,a[50005],b[50005],ans;
 6 int main(){
 7     scanf("%d%d",&n,&m);
 8     for(int i=1;i<=m;++i)scanf("%d%d",&a[i],&b[i]);
 9     for(int i=1;i<=n;++i)B[i][i]=1;
10     for(int i=1;i<=n;++i)for(int j=m;j;--j)
11         if(B[i][a[j]]&&B[i][b[j]]){B[i].reset();break;}
12         else if(B[i][a[j]]&&!B[i][b[j]])B[i][b[j]]=1;
13         else if(B[i][b[j]]&&!B[i][a[j]])B[i][a[j]]=1;
14     for(int i=1;i<=n;++i)if(B[i].any())for(int j=i+1;j<=n;++j)if(B[j].any()&&(B[i]&B[j]).none())ans++;
15     printf("%d\n",ans);
16 }
View Code

 


 

什么时候才能回到原来的状态啊。。。

为什么会这么菜啊。。。

可是我好像会做啊。。。


 

posted @ 2019-10-01 14:45  DeepinC  阅读(217)  评论(1编辑  收藏  举报