zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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 floor,所以求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
    ",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
    ",ans[i]);
    124     return 0;
    125 }
    View Code

    d2t3分身术

    什么神仙题,不会

  • 相关阅读:
    在Win7 64位电脑上安装Sql Server 2008 R2 Express
    尝试u盘重装系统
    摘自《北方人》
    编写一个换算GPA 的Application 程序,对于学生学习的每门课程,都输入两个整数:考试成绩和学分,考试成绩按如下公式换算: 85~100:4 75~84:3 60~74:2 45~59:1 44以下:0 GPA等于换算后每门课的成绩的学分加权平均值
    java编程题
    生成器并发处理其实就是函数的切换
    生成器与文档结合
    生成器函数
    生成器表达式、三元表达式、列表解析
    迭代,列表,字典,文件迭代
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8921880.html
Copyright © 2011-2022 走看看