2019.10.08题解

T1

用一个堆维护最小的是谁,每次加入一个值x时查询堆顶是否小于x,有则买top卖x,之后分为是不是反悔操作判断要不要把pop。

然而好像其他人都push两个来进行反悔操作。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<queue>
 6 #define int long long
 7 using namespace std;
 8 int ans,n;
 9 struct point
10 {
11         int x,y;
12         friend bool operator <(point l,point r)
13         {
14                 return l.x>r.x;
15         }
16 };
17 priority_queue<point>q;
18 signed main()
19 {
20         //freopen("1.in","r",stdin);
21         //freopen("1.out","w",stdout);
22         scanf("%lld",&n);
23         for(int i=1,x;i<=n;i++)
24         {
25                 scanf("%lld",&x);
26                 point tmp={x,0};
27                 if(q.size()&&q.top().x<x)
28                 {
29                         ans+=x-q.top().x;
30                         if(!q.top().y) q.pop();
31                         else 
32                         {
33                                 point res=q.top();
34                                 q.pop();
35                                 res.y=0;
36                                 q.push(res);
37                         }
38                         tmp.y=1;
39                 }
40                 q.push(tmp);
41         }
42         printf("%lld",ans);
43         return 0;
44 }
T1

T2

1>

$ S(n,m)=sum_{i=0}^{m}C_{n}^{i} $

$ S(n,m)=sum_{i=0}^{m-1}C_{n-1}^{i}+sum_{i=0}^{m}C_{n-1}^{i} $

$ S(n,m)=S(n-1,m-1)+S(n-1,m) $

$ S(n,m)=2*S(n-1,m)-C_{n-1}^{m} $

2>

$ S(n,m)=S(n,m-1)+C_{n}^{m} $

有了这两个递推式子便可以用莫队O(nsqrt(n))解决啦。

ps:这里的莫队是一维的,可以把n,m看成一条线段。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define int long long
 7 using namespace std;
 8 const int k=490,N=1e5+10,mod=1e9+7;
 9 int ans,n,m,id,q,S,fac[N],inv[N],f[N];
10 struct question{int x,y,id;}a[N];
11 bool comp(question l,question r)
12 {
13         if(l.x/k==r.x/k) return (l.x/k)&1?l.y>r.y:l.y<r.y;
14         return l.x/k<r.x/k;
15 }
16 int read()
17 {
18         int sum,k=1;char s;
19         while(s=getchar(),s<'0'||s>'9') if(s=='-') k=-1;sum=s-'0';
20         while(s=getchar(),s>='0'&&s<='9') sum=sum*10+s-'0';
21         return k*sum;
22 }
23 int qpow(int x,int y,int z)
24 {
25         int sum=1;
26         while(y)
27         {
28                 if(y&1) sum=sum*x%z;
29                 y>>=1;
30                 x=x*x%z;
31         }
32         return sum;
33 }
34 int C(int x,int y)
35 {
36         if(x<y) return 0;
37         return fac[x]*inv[y]%mod*inv[x-y]%mod;
38 }
39 signed main()
40 {
41         //freopen("1.in","r",stdin);
42         //freopen("2.out","w",stdout);
43         id=read(),q=read();
44         for(int i=1;i<=q;i++)
45         {
46                 a[i].x=read(),a[i].y=read(),a[i].id=i;
47                 S=max(S,max(a[i].x,a[i].y));
48         }
49         fac[0]=1;
50         for(int i=1;i<=S;i++) fac[i]=fac[i-1]*i%mod;
51         inv[S]=qpow(fac[S],mod-2,mod);
52         for(int i=S-1;i>-1;i--) inv[i]=inv[i+1]*(i+1)%mod;
53         sort(a+1,a+q+1,comp);
54         n=m=0;ans=1;
55         for(int i=1;i<=q;i++)
56         {
57                 while(n<a[i].x) n++,ans=(ans*2-C(n-1,m)+mod)%mod;
58                 while(n>a[i].x) n--,ans=(ans+C(n,m))%mod*inv[2]%mod;
59                 while(m<a[i].y) m++,ans=(ans+C(n,m))%mod;
60                 while(m>a[i].y) m--,ans=(ans-C(n,m+1)+mod)%mod;
61                 f[a[i].id]=ans;
62         }
63         for(int i=1;i<=q;i++) printf("%lld
",f[i]);
64         return 0;
65 }
View Code

T3

首先有一个重要性质:本题的边点同阶

疯狂模拟即可

原文地址:https://www.cnblogs.com/AthosD/p/11636562.html