【20161114模拟赛】

 

 


这题逆序做就好了。

然后我要记录当前的点要乘l的多少次方

在这里被卡了6个点。。因为这个最终的点数很大,指数也要mod,指数mod的应该是phi(mod),因为mod是个质数,所以应该%(mod-1)。

当然可以直接记录数值然后就避开这个问题。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 
 7 typedef long long LL;///////
 8 const LL N=1000100,M=1000100,mod=998244353;
 9 LL n,m,L,cost[N],sum[N];
10 LL ql,q[M],st[M],qc[M];
11 
12 LL quickpow(LL x,LL y)
13 {
14     LL ans=1;
15     while(y)
16     {
17         if(y&1) ans=ans*x%mod;
18         x=x*x%mod;
19         y/=2;
20     }
21     return ans;
22 }
23 
24 int main()
25 {
26     freopen("a.in","r",stdin);
27     freopen("a.out","w",stdout);
28     scanf("%I64d%I64d%I64d",&n,&m,&L);
29     for(LL i=1;i<=n;i++) cost[i]=i,sum[i]=1;
30     LL x,k,now;ql=0;
31     memset(st,0,sizeof(st));
32     for(LL i=1;i<=m;i++)
33     {
34         scanf("%I64d%I64d",&k,&qc[i]);
35         st[i]=ql+1;
36         for(LL j=1;j<=k;j++)
37         {
38             scanf("%I64d",&x);
39             q[++ql]=x;
40         }
41     }
42     st[m+1]=ql+1;
43     /*
44     for(LL i=1;i<=m;i++)
45     {
46         printf("%d\n",qc[i]);
47         for(LL j=st[i];j<st[i+1];j++)
48             printf("%d ",q[j]);
49         printf("\n");
50     }
51     */
52     LL t0,t1;
53     for(LL i=m;i>=1;i--)
54     {
55         x=qc[i];
56         t0=0,t1=0;
57         for(LL j=st[i];j<st[i+1];j++)
58         {
59             now=(cost[q[j]]*quickpow(L,t1))%mod;
60             t0=(t0+now)%mod;
61             t1=(t1+sum[q[j]])%(mod-1);
62         }
63         cost[x]=t0;sum[x]=t1;
64         // printf("cost %I64d = %I64d  sum = %I64d\n",x,t0,t1);
65     }
66     printf("%I64d\n",cost[1]);
67     return 0;
68 }

 


这个c(n+k-1,k)也就是重复排列,n种球中选择k个。

证明:

1 假设选择了x种。
2 ans=sigma(C(n,x)*C(k-x+x-1,x-1)) (1<=x<=n)//隔板法
3 =sigma(C(n,x)*C(k-1,k-1))
4 =C(n+k-1,k)

这题中k很大。。然后我们就转化成C(n+k-1,n-1).

然后直接容斥定理做,假设某几个一定爆掉了。

第二次容斥定理。。哭。。QAQ。。

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 
 9 typedef long long LL;
10 const LL N=25,S=5000100,mod=998244353;
11 LL n,K,a[N],ny[N];
12 
13 LL quickpow(LL x,LL y)
14 {
15     LL ans=1;
16     while(y)
17     {
18         if(y&1) ans=ans*x%mod;
19         x=x*x%mod;
20         y/=2;
21     }
22     return ans;
23 }
24 
25 LL find_c(LL k)
26 {
27     LL ans=1;
28     for(LL i=0;i<n-1;i++)  ans=ans*(n+k-1-i)%mod;
29     for(LL i=0;i<n-1;i++)  ans=ans*ny[n-1-i]%mod;
30     return ans;
31 }
32 
33 int main()
34 {
35     freopen("b.in","r",stdin);
36     freopen("b.out","w",stdout);
37     scanf("%I64d%I64d",&n,&K);
38     for(LL i=1;i<=n;i++)
39     {
40         ny[i]=quickpow(i,mod-2);
41     }
42     for(LL i=0;i<n;i++)
43     {
44         scanf("%I64d",&a[i]);
45     }
46     LL ans=0;
47     for(LL s=0;s<(1<<n);s++)
48     {
49         LL cnt=0,sum=0,now=0;
50         for(LL i=0;i<n;i++)
51         {
52             if(s&(1<<i)) cnt++,sum+=(a[i]+1);
53         }
54         if(K-sum>=0)
55         {
56             now=find_c(K-sum);
57             if(!(cnt&1)) ans=(ans+now)%mod;
58             else ans=((ans-now)%mod+mod)%mod;
59         }    
60     }
61     printf("%I64d\n",ans);
62     return 0;
63 }

 

 


 

跪%YC。。打整体二分。。

这题我打的是线段树,就是题解上说的这个:

 

 

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 using namespace std;
  6 
  7 const int N=100010,INF=(int)1e9;
  8 int n,m,tl,a[N],ans[N];
  9 struct trnode{
 10     int l,r,lc,rc,lazy,mn,d;
 11 }t[2*N];
 12 
 13 int minn(int x,int y){return x<y ? x:y;}
 14 
 15 int bt(int l,int r)
 16 {
 17     int x=++tl;
 18     t[x].l=l;t[x].r=r;
 19     t[x].lc=t[x].rc=0;
 20     t[x].lazy=0;t[x].mn=INF;
 21     if(l<r)
 22     {
 23         int mid=(l+r)/2;
 24         t[x].lc=bt(l,mid);
 25         t[x].rc=bt(mid+1,r);
 26         int lc=t[x].lc,rc=t[x].rc;
 27         t[x].mn=minn(t[lc].mn,t[rc].mn);
 28     }
 29     else 
 30     {
 31         t[x].mn=a[l];
 32         if(a[l]<=0) {ans[l]=0;t[x].mn=INF;}
 33     }
 34     return x;
 35 }
 36 
 37 void pd(int x)
 38 {
 39     if(t[x].lazy==0) return;
 40     int d=t[x].lazy,lc=t[x].lc,rc=t[x].rc;
 41     t[x].lazy=0;
 42     if(t[x].mn<INF) t[x].mn-=d;
 43     if(lc) t[lc].lazy+=d;
 44     if(rc) t[rc].lazy+=d;
 45 }
 46 
 47 void upd(int x)
 48 {
 49     int lc=t[x].lc,rc=t[x].rc;
 50     pd(lc);pd(rc);
 51     t[x].mn=minn(t[lc].mn,t[rc].mn);
 52 }
 53 
 54 void fd(int x,int d,int id)
 55 {
 56     pd(x);
 57     if(t[x].l==t[x].r) 
 58     {
 59         t[x].d-=d;
 60         t[x].mn=INF;
 61         ans[t[x].l]=id;
 62         return;
 63     }
 64     int lc=t[x].lc,rc=t[x].rc;
 65     pd(lc);pd(rc);
 66     if(t[lc].mn-d<=0) fd(lc,d,id);
 67     else t[lc].lazy+=d;
 68     if(t[rc].mn-d<=0) fd(rc,d,id);
 69     else t[rc].lazy+=d;
 70     upd(x);
 71 }
 72 
 73 void change(int x,int l,int r,int d,int id)
 74 {
 75     pd(x);
 76     if(t[x].l==l && t[x].r==r) 
 77     {
 78         if(t[x].mn-d<=0) fd(x,d,id);
 79         else t[x].lazy+=d,pd(x);
 80         return ;
 81     }
 82     int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/2;
 83     if(r<=mid) change(lc,l,r,d,id);
 84     else if(l>mid) change(rc,l,r,d,id);
 85     else 
 86     {
 87         change(lc,l,mid,d,id);
 88         change(rc,mid+1,r,d,id);
 89     }
 90     upd(x);
 91 }
 92 
 93 void output(int x)
 94 {
 95     printf("x = %d  l = %d  r = %d  mn = %d  lazy = %d\n",x,t[x].l,t[x].r,t[x].mn,t[x].lazy);
 96     if(t[x].lc) output(t[x].lc);
 97     if(t[x].rc) output(t[x].rc);
 98 }
 99 
100 int main()
101 {
102     // freopen("a.in","r",stdin);
103     // freopen("a.out","w",stdout);
104     freopen("c.in","r",stdin);
105     freopen("c.out","w",stdout);
106     int k,x,l,r,d;
107     scanf("%d%d",&n,&m);
108     for(int i=1;i<=n;i++)
109     {
110         scanf("%d",&a[i]);
111     }
112     tl=0;bt(1,n);
113     for(int i=1;i<=n;i++) ans[i]=-1;
114     // memset(ans,-1,sizeof(ans));
115     for(int i=1;i<=m;i++)
116     {
117         scanf("%d%d%d",&l,&r,&d);
118         if(l<=r) change(1,l,r,d,i);
119         else 
120         {
121             change(1,l,n,d,i);
122             change(1,1,r,d,i);
123         }
124         // output(1);
125         // printf("\n");
126     }
127     scanf("%d",&k);
128     for(int i=1;i<=k;i++)
129     {
130         scanf("%d",&x);
131         if(ans[x]==-1) printf("So sad\n");
132         else printf("%d\n",ans[x]);
133     }
134     return 0;
135 }

 

 

 

posted @ 2016-11-14 15:27  拦路雨偏似雪花  阅读(294)  评论(0编辑  收藏  举报