NOI2017

d1t1[NOI2017]整数

加减就是一段区间赋为0/1,这个位置前面第一个0/1变成1/0

线段树维护就可以了,或许常数足够优秀就能过

否则要压位,30个压1位即可.一开始线段树维护了一段区间最左最右的0/1的位置,各种调都只有70多...

然后去参考了一下别人优秀的代码,线段树维护一段区间是不是全0/全1,然后修改一个位置,找到线段树上的一个叶子,修改,然后从它往上跳,以加为例,如果要进位,就从这个叶子开始递归往上的时候,如果目前还没进成,修改的是一段区间的右区间,看看左边是不是全1,如果不是就进位到左边(对左边这棵树调用修改操作,即在线段树上二分最右的0然后往那一位进1),否则的话就把左边的树整体打上变成全0的标记,继续向上递归

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 13 typedef long long LL; 
 14 typedef double db;
 15 using namespace std;
 16 const int N=2000011,bs=30,up=2000007;
 17 const LL mxup=((1<<30)-1);
 18 int n,t1,t2,t3,RS;
 19 
 20 template<typename T> void read(T &x) {
 21     char ch=getchar(); x=0; T f=1;
 22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 23     if(ch=='-') f=-1,ch=getchar();
 24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 25 }
 26 
 27 LL allup[N<<2],allo[N<<2],v[N<<2],lz[N<<2];  //1 :1 2 :0
 28 #define lc x<<1
 29 #define rc ((x<<1)|1)
 30 #define mid ((l+r)>>1)
 31 void update(int x,int l,int r) {
 32     if(l==r) {
 33         allup[x]=(v[l]==mxup);
 34         allo[x]=(v[l]==0); return;
 35     }
 36     allup[x]=(allup[lc]&allup[rc]);
 37     allo[x]=(allo[lc]&allo[rc]);
 38 }
 39 
 40 void change_it(int x,int l,int r,int f) {
 41     if(f==1) allup[x]=1,allo[x]=0;
 42     else allo[x]=1,allup[x]=0;
 43     if(l==r) v[l]=(f==1)?mxup:0;
 44     else lz[x]=f;
 45 }
 46 
 47 void down(int x,int l,int r) {
 48     if(!lz[x]||l==r) return;
 49     change_it(lc,l,mid,lz[x]);
 50     change_it(rc,mid+1,r,lz[x]);
 51     lz[x]=0; return;
 52 }
 53 
 54 void change(int x,int l,int r,int F) {
 55     if(l==r) {
 56         if(F==1) v[l]--; else v[l]++;
 57         update(x,l,r); return;
 58     }
 59     down(x,l,r); 
 60     if((F==1&&!allo[lc])||(F==2&&!allup[lc])) change(lc,l,mid,F);
 61     else { change_it(lc,l,mid,F); change(rc,mid+1,r,F); }
 62     update(x,l,r);
 63 }
 64 
 65 void add(int x,int l,int r,int pos,LL V) {
 66     if(l==r) {
 67         v[l]+=V; RS=0;
 68         if(v[l]>mxup) { v[l]-=(mxup+1); RS=2; } 
 69         else if(v[l]<0) { v[l]+=(mxup+1); RS=1; } 
 70         update(x,l,r); return;
 71     }
 72     down(x,l,r);
 73     if(pos<=mid) add(lc,l,mid,pos,V);
 74     else add(rc,mid+1,r,pos,V);  
 75     if(RS&&pos<=mid) { 
 76         if((RS==2&&!allup[rc])||(RS==1&&!allo[rc])) {
 77             change(rc,mid+1,r,RS); RS=0;
 78         }
 79         else change_it(rc,mid+1,r,RS);
 80     }
 81     update(x,l,r); return;
 82 }
 83 
 84 int get_it(int x,int l,int r,int pos,int f) {
 85     if(l==r) { 
 86         return (v[l]&(1LL<<f))!=0; 
 87     }
 88     down(x,l,r);
 89     if(pos<=mid) return get_it(lc,l,mid,pos,f);
 90     return get_it(rc,mid+1,r,pos,f);
 91 }
 92 
 93 void build(int x,int l,int r) {
 94     if(l==r) { allo[x]=1; allup[x]=0; return; }
 95     build(lc,l,mid); build(rc,mid+1,r);
 96     update(x,l,r);
 97 }
 98 
 99 //#define DEBUG
100 int main() {
101 #ifdef DEBUG
102     freopen("integer.in","r",stdin);
103     freopen("integer.out","w",stdout);
104 #endif
105     read(n); read(t1); read(t2); read(t3);
106     build(1,1,up);
107     For(ti,1,n) {
108         LL o,k,a,b,f,len=0,tp=1,l,r,ql,qr;
109         read(o);
110         if(o==1) {
111             read(a); read(b);
112             if(a<0) f=-1,a=-a; else f=1;
113             while((tp<<1)<=a) { tp<<=1; len++; }
114             l=b; r=b+len; 
115             ql=l/bs+1; qr=r/bs+1;
116             a<<=(l-(ql-1)*bs);
117             if(a&mxup) add(1,1,up,ql,f*(a&mxup));
118             if(a>>bs) add(1,1,up,qr,f*(a>>bs));
119         }
120         else {
121             read(k);
122             printf("%d\n",get_it(1,1,up,k/bs+1,k%bs));    
123         }
124     }
125     return 0;
126 }
127 /*
128 9000 3 4 2
129 1 898032183 19097
130 1 899706564 244829
131 1 430516929 109811
132 1 -116763903 87261
133 1 -675576449 63566
134 1 878664431 199539
135 2 97764
136 */
View Code

 

d1t23823 [NOI2017]蚯蚓排队

一道卡常数的神题(???)

为什么我改到和llj几乎一模一样都过不了呀,我到底是哪里写得不够优秀呀???luogu上T1个点,bz上过了

hash,考虑没有切开的操作时,发现对于连接的操作,暴力计算横跨连接点的长度小于50的串,每个串只会横跨链接点一次,复杂度就是k*n

对于切除操作,复杂度是k*k*c,连回去还是k*k*c的

所以直接hash就可以了.

大常数选手色色发抖.

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #define For(i,a,b) for(register int i=(a);i<=(b);++i)
 12 #define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
 13 const int N=3e5+7,bs=13,p1=10233333,p2=998244353;
 14 typedef long long LL; 
 15 typedef unsigned long long uLL;
 16 typedef double db;
 17 using namespace std;
 18 int n,m,v[N];
 19 uLL power2[55];
 20 char s[N];
 21 
 22 template<typename T> void read(T &x) {
 23     char ch=getchar(); x=0; T f=1;
 24     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 25     if(ch=='-') f=-1,ch=getchar();
 26     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 27 }
 28 
 29 int tot,fir[p1+7],nxt[p1+7],cnt[p1+7];
 30 uLL H[p1+7];
 31 void add(int H1,uLL H2,int v) {
 32     for(int i=fir[H1];i;i=nxt[i]) if(H[i]==H2) {    
 33         cnt[i]+=v; return;
 34     }
 35     nxt[++tot]=fir[H1]; fir[H1]=tot; H[tot]=H2; cnt[tot]=v;
 36 }
 37 
 38 int qry(int H1,uLL H2) {
 39     for(int i=fir[H1];i;i=nxt[i]) if(H[i]==H2) return cnt[i];
 40     return 0;
 41 }
 42 
 43 int nx[N],pr[N],sta[N],top;
 44 void dfspr(int x,int pos) {
 45     if(pos<50&&pr[x]) dfspr(pr[x],pos+1);
 46     sta[++top]=v[x];
 47 }
 48 
 49 void dfsnx(int x,int pos) {
 50     sta[++top]=v[x];
 51     if(pos<50&&nx[x]) dfsnx(nx[x],pos+1);
 52 }
 53  
 54 uLL prH2[N];
 55 void pre() {
 56     For(i,1,top) 
 57         prH2[i]=prH2[i-1]*bs+sta[i];
 58 }
 59 
 60 void get_H(int l,int r,uLL &H2) {
 61     l--;
 62     H2=prH2[r]-prH2[l]*power2[r-l];
 63 }
 64 
 65 //#define DEBUG
 66 int main() {
 67 #ifdef DEBUG
 68     freopen("queue.in","r",stdin);
 69     freopen("queue.out","w",stdout);
 70 #endif
 71     read(n); read(m);
 72     power2[0]=1;
 73     For(i,1,55) power2[i]=power2[i-1]*bs;
 74     For(i,1,n) { read(v[i]); add(v[i],v[i],1); }
 75     For(i,1,m) {
 76         int o,x,y,k;
 77         read(o);
 78         if(o==1) {
 79             read(x); read(y); top=0;
 80             int ll,rr;
 81             dfspr(x,1); ll=top;
 82             dfsnx(y,1); rr=top-ll;
 83             //pre();
 84             For(i,1,ll) {
 85                    uLL H2=0;
 86                    For(j,i,ll) H2=H2*bs+sta[j];
 87                 For(j,1,rr) {
 88                     //int H1=0; uLL H2=0;
 89                     //get_H(i,ll+j,H2);
 90                     H2=H2*bs+sta[ll+j];
 91                     int H1=H2%p1;
 92                     add(H1,H2,1);
 93                 }    
 94             }    
 95             nx[x]=y; pr[y]=x;
 96         }
 97         else if(o==2) {
 98             read(x);
 99             top=0;
100             int ll,rr;
101             dfspr(x,1); ll=top; 
102             dfsnx(nx[x],1); rr=top-ll;
103             /*pre();
104             For(i,1,ll) 
105                 For(j,1,rr) {
106                     int H1=0; uLL H2=0;
107                     get_H(i,ll+j,H2);
108                     H1=H2%p1;
109                     add(H1,H2,-1);
110                 }    */
111             For(i,1,ll) {
112                    uLL H2=0;
113                    For(j,i,ll) H2=H2*bs+sta[j];
114                 For(j,1,rr) {
115                     //int H1=0; uLL H2=0;
116                     //get_H(i,ll+j,H2);
117                     H2=H2*bs+sta[ll+j];
118                     int H1=H2%p1;
119                     add(H1,H2,-1);
120                 }    
121             }    
122             pr[nx[x]]=0; nx[x]=0;
123         }
124         else {
125             scanf("%s",s); int len=strlen(s);
126             top=0;
127             For(i,0,len-1) sta[++top]=s[i]-'0'; 
128             pre();
129             read(k);
130             LL ans=1;
131             For(i,1,len-k+1) {
132                 int H1=0; uLL H2=0;
133                 get_H(i,i+k-1,H2);
134                 H1=H2%p1;
135                 ans=ans*qry(H1,H2)%p2;
136             }
137             printf("%lld\n",ans);
138         }
139     }
140     return 0;
141 }
View Code

 

d1t3泳池

???我不会呀,等着sxy给我讲

-------------------------------4-25upd-----------------------------

ans[k]表示最大子矩阵小于等于k的答案,那么答案就是ans[k]-ans[k-1]

如何计算ans[k]

f[i]表示前i行最大子矩阵小于等于k的概率

ans[k]=f[n]

发现泳池高大于最大的k,即可以看作泳池无限高.

如何求f:

定义g[i][j]表示连续的j列靠泳池边的前i行都是安全的,并且最小子矩阵小于等于k的概率

h[i][j]表示连续的j列靠泳池边的前i行都是安全的,(i+1,j)是危险的,并且最小子矩阵小于等于k的概率

$f[i]=\sum_{j=1}^{min(k,i)}f[i-j]*g[1][j-1]*(1-p)$

这是一个k阶常系数线性齐次递推,可以用多项式取模优化到n^2或nlogklogn

如何求g,h

$g[k][1]=h[k][1]=p^k*(1-p)$

$g[i][0]=h[i][0]=1$

$g[i][j]=\sum_{t=0}^jh[i][t]*g[i+1][j-t]$

$h[i][j]=\sum_{t=0}^{j-1}h[i][t]*g[i+1][j-t-1]*p^i*(1-p)$

$第i行,j<=\lfloor k/i \rfloor,所以求g,h是k^2的$

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #include<map>
 12 const int N=1007,mod=998244353;
 13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 15 typedef long long LL; 
 16 typedef double db;
 17 using namespace std;
 18 LL n,x,y,p,h[N][N],g[N][N],power[N],f[N],A[N];
 19 
 20 template<typename T> void read(T &x) {
 21     char ch=getchar(); x=0; T f=1;
 22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 23     if(ch=='-') f=-1,ch=getchar();
 24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 25 }
 26 
 27 LL ksm(LL a,LL b) {
 28     LL rs=1,bs=a;
 29     while(b) {
 30         if(b&1) rs=rs*bs%mod;
 31         bs=bs*bs%mod;
 32         b>>=1;
 33     }
 34     return rs;
 35 }
 36 
 37 LL mo(LL x) { return x>=mod?x-mod:x; }
 38 
 39 LL rs[N<<1],bs[N<<1],c[N<<1];
 40 LL cheng(LL a[],LL b[],int k) {
 41     memset(c,0,sizeof(c));
 42     For(i,0,k-1) For(j,0,k-1) 
 43         c[i+j]=mo(c[i+j]+a[i]*b[j]%mod);
 44     Rep(i,2*k-1,k) For(j,1,k) 
 45         c[i-j]=mo(c[i-j]+A[j]*c[i]%mod);
 46     For(i,0,k-1) a[i]=c[i];
 47 }
 48 
 49 void mul(LL b,int k) {
 50     rs[0]=1; bs[1]=1;
 51     while(b) {
 52         if(b&1) cheng(rs,bs,k);
 53         cheng(bs,bs,k);
 54         b>>=1;
 55     }
 56 }
 57 
 58 LL solve(LL k) {
 59     memset(g,0,sizeof(g));
 60     memset(h,0,sizeof(h));
 61     memset(f,0,sizeof(f));
 62     memset(rs,0,sizeof(rs));
 63     memset(bs,0,sizeof(bs));
 64     g[k][1]=h[k][1]=power[k]*(1-p+mod)%mod;
 65     g[k][0]=h[k][0]=1;
 66     Rep(i,k-1,1) {
 67         g[i][0]=h[i][0]=1;
 68         For(j,1,k/i)  
 69             For(t,0,j) {
 70                 if(t<=j-1) h[i][j]=mo(h[i][j]+h[i][t]*g[i+1][j-t-1]%mod*power[i]%mod*(1-p+mod)%mod);
 71                 g[i][j]=mo(g[i][j]+h[i][t]*g[i+1][j-t]%mod);
 72             }
 73     } 
 74     f[0]=1;
 75     For(i,1,k) {
 76         For(j,1,i) 
 77             f[i]=mo(f[i]+f[i-j]*g[1][j-1]%mod*(1-p+mod)%mod);
 78         if(i<=k) f[i]=mo(f[i]+g[1][i]);
 79     }
 80     if(n<=k) {
 81         LL ans=f[n];
 82         return ans;
 83     }
 84     else {
 85         k++;
 86         For(i,1,k) A[i]=g[1][i-1]*(1-p+mod)%mod;
 87         mul(n,k); LL res=0;
 88         For(i,0,k-1) res=mo(res+rs[i]*f[i]%mod);
 89         return res;  
 90     }
 91 } 
 92 
 93 //#define DEBUG
 94 int main() {
 95 #ifdef DEBUG
 96     freopen("1.in","r",stdin);
 97     //freopen(".out","w",stdout);
 98 #endif
 99     LL k;
100     read(n); read(k); read(x); read(y);
101     p=x*ksm(y,mod-2)%mod;
102     power[0]=1;
103     For(i,1,k) power[i]=power[i-1]*p%mod;
104     LL ans11=solve(k);
105     LL ans22=solve(k-1);
106     LL ans=(ans11-ans22+mod)%mod;
107     printf("%lld\n",ans);
108     return 0;
109 }
View Code

 

---------------------------------------upd---------------------------------一开始f没有加上g[1][i],a只处理到k,还不知道为什么wa....

实际上f的转移是

$f[i]=\sum_{j=1}^{min(k+1,i)}f[i-j]*g[1][j-1]*(1-p)$

本来就是一个k+1阶的递推

 

d2t1游戏

怎么是一道2-sat裸题呀

暴力枚举每种x当作a,b,c中的哪一种,然后2-sat判断即可

2-sat板子都写错了...连边都没连对称啊我是个zz吧..

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 13 const int N=400007;
 14 typedef long long LL; 
 15 typedef double db;
 16 using namespace std;
 17 int n,d,m,no[10],col[N],tid[N][4]; // A:1 B:2 C:3
 18 char s[N],ss[10];
 19 
 20 template<typename T> void read(T &x) {
 21     char ch=getchar(); x=0; T f=1;
 22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 23     if(ch=='-') f=-1,ch=getchar();
 24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 25 }
 26 
 27 struct node {
 28     int a,b,x,y;
 29 }q[N];
 30 
 31 int ecnt,fir[N],nxt[N<<1],to[N<<1];
 32 void add(int u,int v) {
 33     nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
 34 }
 35 
 36 int dfs_clock,dfn[N],low[N],bl[N],op[N],tot,sta[N],top;
 37 void tarjan(int x) {
 38     dfn[x]=low[x]=++dfs_clock;
 39     sta[++top]=x;
 40     for(int i=fir[x];i;i=nxt[i]) {
 41         if(!dfn[to[i]]) {
 42             tarjan(to[i]);
 43             low[x]=min(low[x],low[to[i]]);
 44         }
 45         else if(!bl[to[i]]) low[x]=min(low[x],dfn[to[i]]);
 46     }
 47     if(low[x]==dfn[x]) {
 48         tot++;
 49         for(;;) {
 50             int y=sta[top--];
 51             bl[y]=tot;
 52             if(y==x) break;
 53         }
 54     }
 55 }
 56 
 57 int fi[N],nx[N],tt[N],ec,in[N];
 58 void ADD(int u,int v) {
 59     nx[++ec]=fi[u]; fi[u]=ec; tt[ec]=v; in[v]++;
 60 }
 61 
 62 queue<int>que;
 63 int vis[N];
 64 void dfs(int x) {
 65     vis[x]=-1;
 66     for(int i=fi[x];i;i=nx[i]) if(!vis[tt[i]]) 
 67         dfs(tt[i]);
 68 }
 69 
 70 void tpsort() {
 71     For(i,1,tot) if(!in[i]) que.push(i);
 72     while(!que.empty()) {
 73         int x=que.front();
 74         que.pop();
 75         if(vis[x]) continue;
 76         vis[x]=1;
 77         dfs(op[x]);
 78         for(int i=fi[x];i;i=nx[i]) {
 79             in[tt[i]]--;
 80             if(!in[tt[i]]) que.push(tt[i]);
 81         } 
 82     }        
 83 }
 84 
 85 int main() {
 86 #ifdef DEBUG
 87     freopen(".in","r",stdin);
 88     freopen(".out","w",stdout);
 89 #endif
 90     read(n); read(d);
 91     scanf("%s",s+1);
 92     read(m);
 93     For(i,1,m) {
 94         read(q[i].a); scanf("%s",ss); q[i].x=ss[0]-'A'+1;
 95         read(q[i].b); scanf("%s",ss); q[i].y=ss[0]-'A'+1;
 96     }
 97     int up=(3<<d)-1;
 98     For(ti,0,up) {
 99         For(i,1,n*2) fir[i]=0,dfn[i]=0,bl[i]=0,vis[i]=0; 
100         int tp=ti; ecnt=0; tot=0;
101         For(i,1,d) {
102             no[i]=tp%3; tp/=3;
103         }
104         int pos=0;
105         For(i,1,n) {
106             if(s[i]=='x') pos++;
107             if(s[i]=='a'||(s[i]=='x'&&no[pos]==0)) tid[i][1]=0,tid[i][2]=i,tid[i][3]=i+n,col[i]=2,col[i+n]=3;
108             if(s[i]=='b'||(s[i]=='x'&&no[pos]==1)) tid[i][1]=i,tid[i][2]=0,tid[i][3]=i+n,col[i]=1,col[i+n]=3;
109             if(s[i]=='c'||(s[i]=='x'&&no[pos]==2)) tid[i][1]=i,tid[i][2]=i+n,tid[i][3]=0,col[i]=1,col[i+n]=2;
110         }
111         For(i,1,m) {
112             int a=q[i].a,x=q[i].x,b=q[i].b,y=q[i].y;
113             if(a==b&&x==y) continue;
114             if(tid[a][x]) {
115                 if(tid[b][y]) {
116                     add(tid[a][x],tid[b][y]);
117                     int z=tid[a][x]==a?a+n:a;
118                     int w=tid[b][y]==b?b+n:b;
119                     add(w,z);
120                 }
121                 else {
122                     int z;
123                     For(j,1,3) if(tid[a][j]&&j!=x) z=tid[a][j];
124                     add(tid[a][x],z);
125                 }
126             }
127         }
128         For(i,1,n*2) if(!dfn[i]) tarjan(i);
129         int ok=1;
130         For(i,1,n) {
131             if(bl[i]==bl[i+n]) {
132                 ok=0; break;
133             }
134             op[bl[i]]=bl[i+n];
135             op[bl[i+n]]=bl[i];
136         }
137         if(ok) {
138             For(i,1,n*2) {
139                 for(int j=fir[i];j;j=nxt[j]) if(bl[to[j]]!=bl[i]) 
140                     ADD(bl[to[j]],bl[i]);
141             }
142             tpsort();
143             For(i,1,n) {
144                 if(vis[bl[i]]==1) printf("%c",'A'+col[i]-1);
145                 else printf("%c",'A'+col[i+n]-1);
146             }
147             puts("");
148             return 0;
149         }
150     }
151     puts("-1");
152     return 0;
153 }
View Code

 

d2t2蔬菜

把每种蔬菜分成两份,最后一个过期的蔬菜单独一份,价值为蔬菜的价值加上额外价值

考虑如果知道了i天的答案,对于i-1天的答案,就是从i的答案中去掉i的答案中买的个数减去i-1天能买的个数那么多个价值最小的蔬菜后的答案

那么只要求出最大的一天的答案就可以了

用堆维护蔬菜价值,每次取出价值最大的,贪心(价值相同与过期天数无关,只要按价值放一定是最优的)地从后往前往可以继续放的天数中放,用并查集维护每一天前面第一个还可以继续放的天数

写的时候总觉得有什么不对劲,写文件名时才发现我给蔬菜的结构题命名为了fruit 2333

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 12 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 13 const int N=1e5+7;
 14 typedef long long LL; 
 15 typedef double db;
 16 using namespace std;
 17 int n,m,k,a[N],s[N],c[N],x[N],canuse[N],cntnow;
 18 LL ans[N],ansnow;
 19 
 20 template<typename T> void read(T &x) {
 21     char ch=getchar(); x=0; T f=1;
 22     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 23     if(ch=='-') f=-1,ch=getchar();
 24     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 25 }
 26 
 27 struct Q {
 28     int id,ti;
 29     friend bool operator <(const Q&A,const Q&B) {
 30         return A.ti>B.ti;
 31     }
 32 }q[N];
 33 
 34 struct ft {
 35     int id,ti,cnt;
 36     LL val;
 37     ft(){}
 38     ft(int id,int ti,int cnt,LL val):id(id),ti(ti),cnt(cnt),val(val){}
 39     friend bool operator <(const ft&A,const ft&B) {
 40         return A.val<B.val;
 41     }
 42 }f[N];
 43 
 44 int fa[N];
 45 int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); }
 46 
 47 priority_queue<ft>que;
 48 
 49 struct node {
 50     LL val;
 51     node(){}
 52     node(LL val):val(val){}
 53     friend bool operator <(const node&A,const node&B) {
 54         return A.val>B.val;
 55     }
 56 };
 57 
 58 priority_queue<node>qu;
 59 
 60 void solve(int days) {
 61     For(i,1,n) {
 62         int tp=x[i]?c[i]/x[i]:days;
 63         if(x[i]&&c[i]%x[i]) tp++;
 64         que.push(ft(i,tp,1,s[i]+a[i]));
 65         tp=x[i]?(c[i]-1)/x[i]:days;
 66         if(x[i]&&(c[i]-1)%x[i]) tp++;
 67         que.push(ft(i,0,c[i]-1,a[i]));
 68     }
 69     For(i,1,days) fa[i]=i,canuse[i]=m;
 70     for(;;) {
 71         if(find(days)==0||que.empty()) break;
 72         ft tp=que.top();
 73         que.pop();
 74         Rep(i,tp.cnt,1) {
 75             int ti=x[tp.id]?i/x[tp.id]:days;
 76             if(!tp.ti&&x[tp.id]&&i%x[tp.id]) ti++;
 77             if(tp.ti) ti=tp.ti;
 78             int y=find(min(days,ti));
 79             if(y!=0) {
 80                 canuse[y]--;
 81                 if(!canuse[y]) { fa[y]=find(fa[y-1]); }
 82                 qu.push(node(tp.val));
 83                 ansnow+=tp.val;
 84                 cntnow++;
 85             }
 86             else break;
 87         }
 88     }
 89 }
 90 
 91 void work() {
 92     ans[q[1].id]=ansnow;
 93     For(i,2,k) {
 94         int cc=max(0,cntnow-(q[i].ti*m));
 95         For(j,1,cc) {
 96             node x=qu.top();
 97             qu.pop();
 98             ansnow-=x.val;
 99             cntnow--;
100         }
101         ans[q[i].id]=ansnow;
102     }
103 }
104 
105 //#define DEBUG
106 int main() {
107 #ifdef DEBUG
108     freopen("vegetable.in","r",stdin);
109     freopen("vegetable.out","w",stdout);
110 #endif
111     read(n); read(m); read(k);
112     For(i,1,n) {
113         read(a[i]); read(s[i]);
114         read(c[i]); read(x[i]);
115     }
116     For(i,1,k) {
117         read(q[i].ti);
118         q[i].id=i;
119     }
120     sort(q+1,q+k+1);
121     solve(q[1].ti);
122     work();
123     For(i,1,k) printf("%lld\n",ans[i]);
124     return 0;
125 }
View Code

 

d2t3分身术

什么神仙题,不会

 

posted @ 2018-04-23 21:22  啊宸  阅读(697)  评论(0编辑  收藏  举报