• CQOI2015 解题报告


    CQOI2015终于全做完了~~~,讲一下题吧

    首先这套题比起其他省选还是比较水的,就是5道题比较蛋疼

    T1:[CQOI2015]选数

    这道题还是比较神的。

    首先给个比较神的题解:popoqqq大神的blog这个莫比乌斯反演真的不会

    我们记f[i]为gcd=i*k时的个数,可以得到若数都不相等的话,i一定小于1e5(辗转相减法可得),那么当数都不相等时,答案显然为(r/(k*i)-l/(k*i)+1)^n-(r/(k*i)-l/(k*i)+1)-sigma(f[i*j])然后就能愉快的推出来啦,还有就是当l=1时要特判一下

    CODE:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 #define mod 1000000007
     7 typedef long long ll;
     8 int power(ll x,ll y) {
     9     ll ans=1;
    10     for (;y;y>>=1){
    11         if (y&1) (ans*=x)%=mod;
    12         (x*=x)%=mod;
    13     }
    14     return ans;
    15 }
    16 ll n,l,k,h;
    17 #define maxk 100000
    18 ll f[maxk+10];
    19 int main(){
    20     freopen("number.in","r",stdin);
    21     freopen("number.out","w",stdout);
    22     ll L,H;
    23     scanf("%lld%lld%lld%lld",&n,&k,&L,&H);
    24     ll l=L/k,h=H/k;
    25     if (L%k) l++; 
    26     int tmp=0;
    27     for (int i=maxk;i;i--) {
    28         ll L=l/i,H=h/i;
    29         if (l%i) L++;
    30         f[i]=(power(H-L+1,n)-(H-L+1)+mod)%mod;
    31         for (int j=i+i;j<=maxk;j+=i) f[i]=(f[i]-f[j]+mod)%mod;
    32     }
    33     if (l==1) f[1]++;
    34     printf("%lld
    ",f[1]);
    35     return 0;
    36 }
    View Code

    T2:[CQOI2015]网络吞吐量

    这不就是先求出最短路图后拆点跑个最大流么= =。直接做就行了不要考虑时间问题。。。

    CODE:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<queue>
     6 using namespace std;
     7 typedef long long ll;
     8 #define maxm 150000
     9 #define maxn 1100
    10 struct edges{
    11     int to,next,dist;ll cap;
    12 }edge[maxm*2];
    13 int l,next[maxn];
    14 inline void _addedge(int x,int y,int z){
    15     l++;
    16     edge[l*2]=(edges) {x,next[y],z,0};next[y]=l*2;
    17     edge[l*2+1]=(edges) {y,next[x],z,0};next[x]=l*2+1;
    18 }
    19 inline void addedge(int x,int y,ll z){
    20     l++;
    21     edge[l*2]=(edges){y,next[x],0,z};next[x]=l*2;
    22     edge[l*2+1]=(edges){x,next[y],0,0};next[y]=l*2+1;
    23 }
    24 ll dist[maxn];
    25 bool b[maxn];
    26 typedef pair<ll,int> ii;
    27 priority_queue<ii,vector<ii>,greater<ii> > q;
    28 #define fi first
    29 #define se second
    30 #define inf 0x7fffffff
    31 #define Inf inf*1ll*inf
    32 int n;
    33 inline void dij(){
    34     for (int i=1;i<=n;i++) dist[i]=Inf;    
    35     dist[1]=0;
    36     q.push(ii(0,1));
    37     while (!q.empty()){
    38         ii u=q.top();q.pop();
    39         if (b[u.se]) continue;
    40         b[u.se]=1;
    41         for (int i=next[u.se];i;i=edge[i].next) 
    42             if (dist[u.se]+edge[i].dist<dist[edge[i].to]) {
    43                 dist[edge[i].to]=dist[u.se]+edge[i].dist;
    44                 q.push(ii(dist[edge[i].to],edge[i].to));
    45             }
    46     }
    47 }
    48 int p[maxn],gap[maxn],h[maxn],s,t,N;
    49 ll sap(int u,ll flow){
    50     if (u==t) return flow;
    51     ll cnt=0;
    52     for (int i=p[u];i;i=edge[i].next) 
    53         if (edge[i].cap&&h[edge[i].to]+1==h[u]) {
    54             ll cur=sap(edge[i].to,min(edge[i].cap,flow-cnt));
    55             edge[i].cap-=cur;edge[i^1].cap+=cur;
    56             p[u]=i;
    57             if ((cnt+=cur)==flow) return flow;
    58         }
    59     if (!(--gap[h[u]])) h[s]=N;
    60     gap[++h[u]]++;
    61     p[u]=next[u];
    62     return cnt;
    63 }
    64 inline ll maxflow(){
    65     for (int i=1;i<=N;i++) p[i]=next[i];
    66     ll flow=0;
    67     gap[0]=N;
    68     while (h[s]<N) flow+=sap(s,Inf);
    69     return flow;
    70 }
    71 int main(){
    72     freopen("network.in","r",stdin);
    73     freopen("network.out","w",stdout);
    74     int m;
    75     scanf("%d%d",&n,&m);
    76     N=n*2;
    77     for (int i=1;i<=m;i++) {
    78         int x,y,z;
    79         scanf("%d%d%d",&x,&y,&z);
    80         _addedge(x,y,z);
    81     }
    82     dij();
    83     memset(next,0,sizeof(next));
    84     l=0;
    85     for (int i=2;i<=m*2+1;i+=2) {
    86         if (dist[edge[i].to]==dist[edge[i^1].to]+edge[i].dist)    
    87             addedge(n+edge[i^1].to,edge[i].to,Inf);
    88         else if (dist[edge[i^1].to]==dist[edge[i].to]+edge[i^1].dist)    
    89             addedge(n+edge[i].to,edge[i^1].to,Inf);
    90     }
    91     for (int i=1;i<=n;i++) {
    92         int x;
    93         scanf("%d",&x);
    94         addedge(i,n+i,x);
    95     }
    96     s=1+n,t=n;
    97     printf("%lld
    ",maxflow());
    98     return 0;
    99 }
    View Code

    T3:[CQOI2015]任务查询系统

    描述:戳我~~~

    这道题首先很明显是道裸的数据结构题啦。首先他要求在线,那么按顺序建个函数式线段树就行啦

    自己太弱调了好久= =

    CODE:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 using namespace std;
     7 typedef long long ll;
     8 #define pb push_back
     9 #define maxn 100100
    10 struct qnode{
    11     int x,y,z;
    12 }q[maxn*2];
    13 int l;
    14 inline void add(int x,int y,int z) {q[++l]=(qnode){x,y,z};}
    15 bool cmp(qnode x,qnode y) {return x.x<y.x;}
    16 struct node{int lc,rc,sum;ll s;}t[maxn*64];
    17 #define mid (l+r>>1)
    18 int cnt=0;
    19 int ins(int x,int l,int r,int y,int z){
    20     int root=++cnt;
    21     t[root]=t[x];
    22     t[root].s+=y*z;
    23     t[root].sum+=z;
    24     if (l==r) return root;
    25     if (y<=mid) t[root].lc=ins(t[x].lc,l,mid,y,z);
    26     else t[root].rc=ins(t[x].rc,mid+1,r,y,z);
    27     return root;
    28 }
    29 ll que(int x,int l,int r,int &k){
    30     if (t[x].sum<=k) {
    31         k-=t[x].sum;return t[x].s;
    32     }
    33     if (l==r) {ll ans=l*1ll*k;k=0;return ans;}
    34     ll ans=que(t[x].lc,l,mid,k);
    35     if (k) ans+=que(t[x].rc,mid+1,r,k);
    36     return ans;
    37 }
    38 vector<int> a;
    39 int s[maxn],e[maxn],p[maxn],root[maxn];
    40 int main(){
    41     int n,m;
    42     scanf("%d%d",&n,&m);
    43     a.pb(0);
    44     for (int i=1;i<=n;i++) {
    45         scanf("%d%d%d",s+i,e+i,p+i);
    46         e[i]++;
    47         a.pb(s[i]);a.pb(e[i]);
    48     }
    49     sort(a.begin(),a.end());
    50     a.resize(unique(a.begin(),a.end())-a.begin());
    51     for (int i=1;i<=n;i++) {
    52         add(lower_bound(a.begin(),a.end(),s[i])-a.begin(),p[i],1);
    53         add(lower_bound(a.begin(),a.end(),e[i])-a.begin(),p[i],-1);
    54     }
    55     sort(q+1,q+1+l,cmp);
    56     #define inf 10000000
    57     for (int i=1;i<=l;i++) root[q[i].x]=ins(root[q[i-1].x],1,inf,q[i].y,q[i].z);
    58     ll pre=1;
    59     for (int i=1;i<=m;i++) {
    60         int x,ai,bi,ci;
    61         scanf("%d%d%d%d
    ",&x,&ai,&bi,&ci);
    62         int k=1ll+(ai*1ll*(pre%ci)%ci+bi)%ci;
    63         pre=que(root[upper_bound(a.begin(),a.end(),x)-a.begin()-1],1,inf,k);
    64         printf("%lld
    ",pre);
    65     }
    66     return 0;
    67 }
    View Code

    T4:[CQOI2015]多项式

    描述:戳我~~~

    又是高精度= =

    首先我们可以换一下元,吧x-t换成x那就能得到

    那么就能算5次即可啦,再考虑怎么快速算组合数

    完成啦

    CODE:

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define maxb 4
      6 using namespace std;
      7 char s[10010];
      8 int p[9]={1,10,100,1000,10000,100000,1000000,10000000,100000000};
      9 struct bignum{
     10     int a[10010],n,flag;
     11     bignum(int x){
     12         n=0;memset(a,0,sizeof(a));
     13         flag=x<0?1:0;x=abs(x);
     14         while (x) {a[++n]=x%p[maxb];x/=p[maxb];}
     15         if (!n) n=1;
     16     }
     17     bignum(){n=1;memset(a,0,sizeof(a));flag=0;}
     18     int read(){
     19         scanf("%s",s);
     20         int len=strlen(s);
     21         n=0;
     22         if (len==1&&s[0]=='0') {a[n=1]=0;return 0;}
     23         for (int i=len;i>=1;i-=maxb) {
     24             int t=0;
     25             if (i>maxb) for (int j=i-maxb+1;j<=i;j++) t=t*10+s[j-1]-'0';
     26             else for (int j=1;j<=i;j++) t=t*10+s[j-1]-'0';
     27             a[++n]=t;
     28         } 
     29         return 0;
     30     }
     31     int write(){
     32         if (flag) printf("-");
     33         printf("%d",a[n]);
     34         for (int i=n-1;i>=1;i--) {
     35             for (int j=1;j<maxb;j++) if  (a[i]<p[j]) printf("0"); 
     36             printf("%d",a[i]);
     37         }
     38         printf("
    ");
     39         return 0;
     40     }
     41     int cmp(bignum x){
     42         if (x.n!=n) return (x.n<n);
     43         for (int i=n;i>=1;i--)
     44             if (x.a[i]!=a[i]) return (x.a[i]<a[i]);
     45         return -1;
     46     }
     47     int div(int x){
     48         int s=0;
     49         for (int i=n;i>=1;i--){
     50             s=a[i]+s*p[maxb];
     51             a[i]=s/x;
     52             s%=x;
     53         }
     54         if (n!=1&&!a[n]) n--;
     55         return s;
     56     }
     57 }a,b;
     58 bignum operator + (bignum x,bignum y){
     59     if (x.flag^y.flag && x.cmp(y)==0)swap(x,y);
     60     if (x.flag==y.flag) {
     61         x.n=max(x.n,y.n);
     62         for (int i=1;i<=x.n;i++) {
     63             x.a[i]+=y.a[i];
     64             x.a[i+1]+=x.a[i]/p[maxb];
     65             x.a[i]%=p[maxb];
     66         }
     67         if (x.a[x.n+1]) x.n++;
     68         return x;
     69     }
     70     for (int i=1;i<=x.n;i++) {
     71         x.a[i]-=y.a[i];
     72         if (x.a[i]<0) {x.a[i]+=p[maxb];x.a[i+1]--;}
     73         while (!x.a[x.n]&&x.n>1) x.n--;
     74     }
     75     return x;
     76 }
     77 bignum operator * (bignum x,bignum y){
     78     bignum ans;
     79     if (x.n==1&&x.a[1]==0) return ans;
     80     if (y.n==1&&y.a[1]==0) return ans;
     81     ans.flag=x.flag^y.flag;
     82     for (int i=1;i<=x.n;i++) 
     83         for (int j=1;j<=y.n;j++) {
     84             ans.a[i+j-1]+=x.a[i]*y.a[j];
     85             ans.a[i+j]+=ans.a[i+j-1]/p[maxb];
     86             ans.a[i+j-1]%=p[maxb];
     87         }
     88     int n=x.n+y.n-1;
     89     while (ans.a[n+1]) {
     90         n++;ans.a[n+1]+=ans.a[n]/p[maxb];
     91         ans.a[n]%=p[maxb];
     92     }
     93     ans.n=n;
     94     return ans;
     95 }
     96 int sum;
     97 int main(){
     98     static bignum n,m;
     99     int t;
    100     n.read();
    101     scanf("%d",&t);
    102     m.read();
    103     static int a[4000];
    104     a[0]=1;
    105     for (int i=1;i<=3389;i++) a[i]=(a[i-1]*1234+5678) % 3389;
    106     static bignum tmp=m;
    107     int l=tmp.div(3388);
    108     static bignum ans,c=bignum(1),T=bignum(1);
    109     int cnt=0;
    110     for (bignum i=m;i.cmp(n)!=1;i=i+bignum(1),cnt++) {
    111         ans=ans+c*T*bignum(a[l]);
    112         l=(l+1)%3388;
    113         c=c*(i+bignum(1));
    114         c.div(cnt+1);
    115         T=T*bignum(t);
    116     }
    117     ans.write();
    118     return 0;
    119 }
    View Code

    T5:[CQOI2015]标示设计

    描述:戳我~~~

    首先我们考虑轮廓线,那么每个L可能有四种状态:已经结束,还未开始,还没拐弯,已经拐弯,那么如果从上到下,从左到右做的话,可以发现最多只有3条横边被标记,那么对每个L我们可以用一维来存这个状态,在加上起始状态还有终止状态就行啦,然后已经拐弯的状态一定是在那条竖边上在讨论下就行啦

    由于我是从左到右,从上到下做的,所以每一维就多了1倍的状态,所以在BZ上就光荣的TLE啦,不过在学校的oj上还是能过的。所以代码就不贴啦

  • 相关阅读:
    英国下院通过法案允许合成人兽胚胎
    老外关于思考时间的问与答
    性能测试中用LambdaProbe监控Tomcat
    BT下载原理
    汽车维修行业呼吁大学生加入修车行列
    一个女研究生(高级测试工程师)的职业选择
    微软称20日验证Windows与Office 盗版将黑屏 网友评论
    Xbox摇身变NAS:BT的使用问题与性能测试
    李开复建言大学生:求职中不要把钱看得太重
    IBM雇员将罢工15分钟 为抗议公司裁员
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4461428.html
Copyright © 2020-2023  润新知