常州day3

Task1

小 W 得到了一堆石子,要放在 N 条水平线与 M 条竖直线构成的网格的交点上。
因为小 M 最喜欢矩形了, 小 W 希望知道用 K 个石子最多能找到多少四边平行于坐标轴的
长方形,它的四个角上都恰好放着一枚石子。

对于 100%的数据:N<=30000,保证任意两点不重合,K<=N*M

简单题,枚举即可

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<math.h>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 ll n,m,k,ans,now,a,b,c,p,q;
 9 int main(){
10     freopen("rectangle.in","r",stdin);
11     freopen("rectangle.out","w",stdout);
12     cin>>n>>m>>k;
13     for(int i=1;i<=n;i++){
14         a=i;b=k/i;c=k%i;now=p=q=0;
15         if(b>m) continue;
16         now=(a*(a-1)/2)*(b*(b-1)/2);
17         if(a<n){
18             if(c>b) continue;
19             p=now+c*(c-1)/2*a;
20         }
21         if(b<m){
22             if(c>a) continue; 
23             q=now+c*(c-1)/2*b;
24         }
25         ans=max(ans,max(p,q));
26     }
27     cout<<ans;
28     return 0;
29 }

Task 2

小 W 发现了一个神奇的数列: 这就是著名的 Fibonacci
Sequence = =!。
众所周知,小 M 的数学超级超级好,于是给小 W 出了一道题:
给小 W 两个数 X,Y,其中 X ≤ Y≤ 2^31−1。
小 W 任务就是求出 Fibonacci 数列第 X~Y 项的和除以 10000 的余数。
然而小 W 是数学战五渣,于是只能把这个任务交给机智的你啦。

对于 100%的数据:T<=1000,Y<=2^31-1

简单题,矩阵快速幂裸题

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<math.h>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<string.h>
 7 #define il inline
 8 using namespace std;
 9 const int mod=10000;
10 int base[3][3],ans[3][3],tmp[3][3],s,t,T;
11 il void mul(int a[3][3],int b[3][3],int c[3][3]){
12     memset(tmp,false,sizeof(tmp));
13     for(int i=0;i<3;i++)
14         for(int j=0;j<3;j++)
15             for(int k=0;k<3;k++)
16                 tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j])%mod;
17     for(int i=0;i<3;i++)
18         for(int j=0;j<3;j++)
19             c[i][j]=tmp[i][j];
20 }
21 il int est(int n){
22     if(n==0) return 0;
23     if(n==1) return 1;
24     if(n==2) return 2;
25     memset(base,0,sizeof(base));
26     memset(ans,0,sizeof(ans));
27     ans[0][0]=ans[1][1]=ans[2][2]=1;
28     base[0][1]=base[0][2]=base[1][0]=base[1][1]=base[1][2]=base[2][2]=1;
29     for(int pow=n-2;pow;pow>>=1){
30         if(pow&1) mul(ans,base,ans);
31         mul(base,base,base);
32     }
33     return (ans[0][2]+ans[1][2]+ans[2][2]*2)%mod;
34 }
35 il void init(){
36     scanf("%d%d",&s,&t);
37     printf("%d
",(mod+est(t)-est(s-1))%mod);
38 }
39 int main(){
40     freopen("fibonacci.in","r",stdin);
41     freopen("fibonacci.out","w",stdout);
42     scanf("%d",&T);
43     for(int i=1;i<=T;i++) init();
44     return 0;
45 }

Task 3

小 W 千辛万苦做出了数列题,突然发现小 M 被困进了迷宫里。
迷宫是一个有 N(2≤N≤1000)个顶点 M(N−1≤M≤N∗(N − 1)/2 ) 条边的无向连通图。
设 dist1[i]表示在这个无向连通图中, 顶点 i 到顶点 1 的最短距离。
为了解开迷宫,现在要求小 W 在这个图中删除 M − (N − 1)条边,使得这个迷宫变成一
棵树。设 dist2[i]表示在这棵树中,顶点 i 到顶点 1 的距离。
小 W 的任务是求出有多少种删除方案,使得对于任意的 i,满足 dist1[i]=dist2[i]。
快点帮助小 W 救出小 M 吧!

对于 100%的数据:2≤N≤1000

最短路径树计数

预处理最短路

因为每个节点链接到从1出发的最短路的距离相等节点是等价的

所以直接统计即可

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<stdlib.h>
 4 #include<algorithm>
 5 #include<math.h>
 6 #include<string>
 7 #include<string.h>
 8 #include<queue>
 9 #define il inline
10 using namespace std;
11 const int N=2001;
12 int n,m,M=0,inq[N],d[N],p[N][N],g[N];
13 long long ans=1;
14 queue<int> q;
15 struct edge{int next,to,val;
16 } e[2000001];
17 struct data{int dist,id;
18 } b[N];
19 il void addedge(int x,int y,int z){
20     e[++M]=(edge){g[x],y,z};g[x]=M;
21 }
22 il bool cmp(data a,data b){
23     return a.dist<b.dist;
24 }
25 int main(){
26     freopen("treecount.in","r",stdin);
27     freopen("treecount.out","w",stdout);
28     scanf("%d%d",&n,&m);
29     for(int i=0;i<=n+1;i++)
30         for(int j=0;j<=n+1;j++)
31             p[i][j]=p[j][i]=(1<<20);
32     for(int i=1,x,y,z;i<=m;i++){
33         scanf("%d%d%d",&x,&y,&z);
34         addedge(x,y,z);
35         addedge(y,x,z);
36         p[x][y]=p[y][x]=z;
37     }
38     for(int i=1;i<=n;i++) d[i]=(1<<20);
39     memset(inq,false,sizeof(inq));
40     d[1]=0;q.push(1);
41     while(!q.empty()){
42         int h=q.front();q.pop();inq[h]=false;
43         for(int i=g[h];i;i=e[i].next)
44             if(d[e[i].to]>d[h]+e[i].val){
45                 d[e[i].to]=d[h]+e[i].val;
46                 if(!inq[e[i].to]){
47                     inq[e[i].to]=true;
48                     q.push(e[i].to);
49                 }
50             }
51     }
52     for(int i=1;i<=n;i++){
53         b[i].dist=d[i];
54         b[i].id=i;
55     }
56     sort(b+1,b+n+1,cmp);
57     for(int i=2;i<=n;i++){
58         int cnt=0;
59         for(int j=1;j<i;j++)
60             if(b[j].dist+p[b[j].id][b[i].id]==b[i].dist)
61                 cnt++;
62         ans=ans*cnt%2147483647ll;
63     }
64     cout<<ans;
65     return 0;
66 }
原文地址:https://www.cnblogs.com/ExiledPoet/p/5773624.html