T1 心灵终结
打表找规律。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 long long T,n,m; 8 9 long long solve(long long x){ 10 if(x%4==0)return x; 11 if(x%4==1)return x+1; 12 if(x%4==2)return x+2; 13 if(x%4==3)return x+1; 14 } 15 16 int main(){ 17 scanf("%lld",&T); 18 while(T--){ 19 scanf("%lld%lld",&n,&m); 20 if(m==1||n==1)printf("%lld\n",m*n); 21 else if(n==2)printf("%lld\n",solve(m)); 22 else if(m==2)printf("%lld\n",solve(n)); 23 else printf("%lld\n",(n*m+1)/2); 24 } 25 return 0; 26 }
T2 Super Big Stupid Cross
排序竟然能暴力水过??
正解好像是二分、扫描线加平衡树乱搞吧
反正我不会正解。。。
#include<cstdio> #include<algorithm> using namespace std; #pragma GCC optimize(2) int n,ans,sum1,sum2; struct oo{int x1,y1,x2,y2,len;}f[100001],g[100001]; bool cmp(oo a,oo b){return a.len>b.len;} int main(){ scanf("%d",&n); for(int i=1,a,b,c,d;i<=n;i++){ scanf("%d%d%d%d",&a,&b,&c,&d); if(a>c)swap(a,c);if(b>d)swap(b,d); if(a==c)f[++sum1]=(oo){a,b,c,d,abs(b-d)}; else g[++sum2]=(oo){a,b,c,d,abs(a-c)}; } sort(f+1,f+sum1+1,cmp); sort(g+1,g+sum2+1,cmp); for(int i=1;i<=sum1;i++){ if((ans<<1)>=f[i].len)break; for(int j=1;j<=sum2;j++){ if((ans<<1)>=g[j].len)break; ans=max(ans,min(min(g[j].y1-f[i].y1,f[i].y2-g[j].y1),min(g[j].x2-f[i].x1,f[i].x1-g[j].x1))); } } if(!ans)printf("Human intelligence is really terrible\n"); else printf("%d\n",ans); }
T3 Baby Step
这题用并查集维护一下连通性就好了
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int N=510,inf=1e9; 5 6 int n,m,f[N*N],p; 7 8 int read(){int x=0,f=1;char c=getchar(); 9 while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} 10 while(c<=‘9‘&&c>=‘0‘){x=x*10+c-‘0‘;c=getchar();} 11 return x*f; 12 } 13 14 int find(int x){return f[x]==x?x:f[x]=find(f[x]);} 15 16 int num(int x,int y){ 17 if(x<1||y<1||x==n||y==n)return 0; 18 else return (x-1)*n+y; 19 } 20 21 void get(int x,int y){ 22 int fx=find(x),fy=find(y); 23 if(fx==fy)puts("DAJIA"),p=1; 24 else f[fy]=fx,p=0,puts("HAHA"); 25 } 26 27 int main(){ 28 int x1,y1,x2,y2; 29 n=read();m=read(); 30 for(int i=0;i<=n*n;i++)f[i]=i; 31 for(int i=1;i<=m;i++){ 32 x1=read();y1=read();x2=read();y2=read(); 33 if(i>1) 34 if(p)x1=read(),y1=read(),x2=read(),y2=read(); 35 else for(int i=1;i<5;i++)int t=read(); 36 if(x1>x2)swap(x1,x2);if(y1>y2)swap(y1,y2); 37 if(x1<x2){ 38 int x=num(x1,y1-1),y=num(x1,y1); 39 get(x,y); 40 } 41 else{ 42 int x=num(x1-1,y1),y=num(x1,y1); 43 get(x,y); 44 } 45 } 46 }
T4 压位
高精度+DP
这个DP我以前写过,是USACO的一道原题
这题题目范围很小,可以不像USACO那样优化到\(O(n)\)
\(f[i]\) 代表做到第\(i\)位没有连续的\(>=k\)的方案总数
DP方程为:
$$ f[i]=\sum_{j=i-k+1}^{i-1}f[j]*(d-1) $$
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 int read() 6 { 7 int x=0,f=1; 8 char ch=getchar(); 9 while((ch<‘0‘)||(ch>‘9‘)) 10 { 11 if(ch==‘-‘) 12 { 13 f=-f; 14 } 15 ch=getchar(); 16 } 17 while((ch>=‘0‘)&&(ch<=‘9‘)) 18 { 19 x=x*10+ch-‘0‘; 20 ch=getchar(); 21 } 22 return x*f; 23 } 24 25 const int maxn=8000; 26 const int maxm=100; 27 28 struct bignum 29 { 30 int val[maxn+10]; 31 32 int clear() 33 { 34 memset(val,0,sizeof val); 35 return 0; 36 } 37 }; 38 39 bignum operator +(const bignum &a,const bignum &b) 40 { 41 bignum res; 42 res.val[0]=std::max(a.val[0],b.val[0]); 43 int r=0; 44 for(int i=1; i<=res.val[0]; ++i) 45 { 46 res.val[i]=((i>a.val[0])?0:a.val[i])+((i>b.val[0])?0:b.val[i])+r; 47 r=res.val[i]>>1; 48 res.val[i]&=1; 49 } 50 if(r>0) 51 { 52 res.val[++res.val[0]]=r; 53 } 54 return res; 55 } 56 57 bignum operator *(const bignum &a,const int &b) 58 { 59 bignum res; 60 res.val[0]=a.val[0]; 61 int r=0; 62 for(int i=1; i<=a.val[0]; ++i) 63 { 64 res.val[i]=a.val[i]*b+r; 65 r=res.val[i]>>1; 66 res.val[i]&=1; 67 } 68 while(r) 69 { 70 res.val[++res.val[0]]=r&1; 71 r>>=1; 72 } 73 return res; 74 } 75 76 bignum operator *(const bignum &a,const bignum &b) 77 { 78 bignum res; 79 res.clear(); 80 res.val[0]=a.val[0]+b.val[0]-1; 81 for(int i=1; i<=a.val[0]; ++i) 82 { 83 int r=0; 84 for(int j=1; j<=b.val[0]; ++j) 85 { 86 int k=i+j-1; 87 res.val[k]+=a.val[i]*b.val[j]+r; 88 r=res.val[k]>>1; 89 res.val[k]&=1; 90 } 91 if(r) 92 { 93 res.val[i+b.val[0]]=r; 94 if(i+b.val[0]>res.val[0]) 95 { 96 res.val[0]=i+b.val[0]; 97 } 98 } 99 } 100 return res; 101 } 102 103 bignum f[maxm+10],ans; 104 int d,q,n,k; 105 106 int main() 107 { 108 d=read(); 109 q=read(); 110 n=read(); 111 k=read(); 112 f[0].val[0]=f[0].val[1]=1; 113 for(int i=1; i<k; ++i) 114 { 115 f[i]=f[i-1]*d; 116 } 117 for(int i=k; i<=n; ++i) 118 { 119 bignum sum; 120 sum.clear(); 121 for(int j=i-k+1; j<i; ++j) 122 { 123 sum=sum+f[j]; 124 } 125 f[i]=sum*(d-1); 126 } 127 ans.val[0]=ans.val[1]=1; 128 for(int i=1; i<=q; ++i) 129 { 130 ans=ans*f[n]; 131 } 132 printf("%d\n",ans.val[0]-1); 133 return 0; 134 }
T5 公共子序列
DP模板最长公共子序列求第\(1\)问
然后求第\(2,3\)问就在原来的DP方程后面加一维\(len\)
第\(2,3\)问就能同时求出来了
1 #pragma GCC optimize(2) 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 typedef long long ll; 8 9 const int N=305,P=1<<20; 10 11 int n,m;char s1[N],s2[N]; 12 int mx,sum,ans[N],las1[N],las2[N],last[N]; 13 int f[N][N],g[N][N][N]; 14 15 int main(){ 16 scanf("%s%s",s1+1,s2+1); 17 n=strlen(s1+1),m=strlen(s2+1); 18 for(int i=1;i<=n;++i) 19 for(int j=1;j<=m;++j){ 20 f[i][j]=max(f[i][j],f[i-1][j]); 21 f[i][j]=max(f[i][j],f[i][j-1]); 22 if(s1[i]==s2[j])f[i][j]=max(f[i][j],f[i-1][j-1]+1); 23 } 24 mx=f[n][m]; 25 printf("%d\n",f[n][m]); 26 for(int i=1;i<=n;++i) 27 las1[i]=last[s1[i]],last[s1[i]]=i; 28 memset(last,0,sizeof last); 29 for(int i=1;i<=m;++i) 30 las2[i]=last[s2[i]],last[s2[i]]=i; 31 for(int i=0;i<=n;++i) 32 for(int j=0;j<=m;++j)g[i][j][0]=1; 33 for(int i=1;i<=n;++i) 34 for(int j=1;j<=m;++j) 35 if(s1[i]==s2[j]){ 36 for(int k=1;k<=mx;++k){ 37 g[i][j][k]=(g[i-1][j-1][k]+g[i-1][j-1][k-1])%P; 38 if(las1[i]&&las2[j]) 39 g[i][j][k]=(g[i][j][k]-g[las1[i]-1][las2[j]-1][k-1]+P)%P; 40 } 41 } 42 else 43 for(int k=1;k<=mx;++k) 44 g[i][j][k]=(g[i-1][j][k]+g[i][j-1][k]+P-g[i-1][j-1][k])%P; 45 for(int i=1;i<=mx;++i) 46 sum=(sum+g[n][m][i])%P; 47 printf("%d\n",sum); 48 for(int i=1;i<=mx;++i) 49 printf("%d\n",g[n][m][i]); 50 return 0; 51 }
T6
扫描线加线段树
要维护这个三元组
线段树要维护区间和还有区间最大值
原文地址:https://www.cnblogs.com/olm2598827139/p/9800685.html
时间: 2024-10-05 05:04:34