20/0/0/0
无话可说。
1207. 遥控车 (Standard IO)
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSet企图使用trie+暴力匹配,炸了。
正解:直接对字符串排序,二分查找。
下面那个题就是求斐波那契数列,要用高精。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e4+10; 4 int n,m,ans; 5 string s[N]; 6 string c; 7 struct bigint{ 8 char num[100000]; 9 int len; 10 bigint operator =(const bigint &t){ 11 strcpy(num,t.num); 12 len=t.len; 13 }//也许这个没啥卵用…… 14 bigint operator +(const bigint &t){ 15 bigint tmp; 16 tmp.len=0; 17 for(int i=0,g=0;g||i<len||i<t.len;i++){ 18 int now=g; 19 if(i<len) now+=num[i]-'0'; 20 if(i<t.len) now+=t.num[i]-'0'; 21 tmp.num[tmp.len++]=now%10+'0'; 22 g=now/10; 23 } 24 return tmp; 25 } 26 }fib[4]; 27 int main(){ 28 scanf("%d%d",&n,&m); 29 for(int i=1;i<=n;i++) cin>>s[i]; 30 sort(s+1,s+n+1); 31 for(int i=1;i<=m;i++){ 32 cin>>c; 33 int pos=lower_bound(s+1,s+n+1,c)-s; 34 bool flag=1; 35 for(int j=0;j<c.size();j++){ 36 if(c[j]!=s[pos][j]){ 37 flag=0;break; 38 } 39 } 40 ans+=flag; 41 } 42 printf("%d ",ans); 43 fib[0]=(bigint){"1",1}; 44 fib[1]=(bigint){"1",1}; 45 for(int i=2;i<=n;i++){ 46 fib[i%3]=fib[(i-1)%3]+fib[(i-2)%3]; 47 } 48 for(int i=fib[n%3].len-1;i>=0;i--){ 49 cout<<fib[n%3].num[i]; 50 } 51 return 0; 52 }
简单来说就是求区间中位数。
用一个大根堆和一个小根堆搞一下即可。
还是讲一下吧:
就是中位数可以看做从小到大排序好的序列拆成两半中间的那个数字,可以类似的模拟这个过程,前半部分是从小到大的一个大根堆,后半部分是一个从大到小的小根堆,堆顶是最接近中位数的数字。
也可以用主席树(忘了咋写,不写了)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 ll read(){ 5 ll x=0,f=1; 6 char c=getchar(); 7 while(!isdigit(c)){ 8 if(c=='-') f=-1; 9 c=getchar(); 10 } 11 while(isdigit(c)){ 12 x=(x<<1)+(x<<3)+(c^48); 13 c=getchar(); 14 } 15 return x*f; 16 } 17 const ll N=1010; 18 ll n,m; 19 ll ans,bsum,ssum; 20 ll a[N]; 21 ll mid[N][N]; 22 priority_queue<int,vector<int>,less<int> > big; 23 priority_queue<int,vector<int>,greater<int> > small; 24 int main(){ 25 n=read();m=read(); 26 for(int i=1;i<=n;i++) a[i]=read(); 27 for(int i=1;i<=n;i++){ 28 while(!big.empty()) big.pop(); 29 while(!small.empty()) small.pop(); 30 bsum=ssum=0; 31 for(int j=i;j<=n;j++){ 32 if(big.size()==small.size()){ 33 big.push(a[j]); 34 bsum+=a[j]; 35 } 36 else{ 37 small.push(a[j]); 38 ssum+=a[j]; 39 } 40 if(big.size()&&small.size()){ 41 int bx=big.top(),sx=small.top(); 42 if(sx<bx){ 43 small.pop(); 44 big.pop(); 45 small.push(bx); 46 big.push(sx); 47 ssum=ssum-sx+bx; 48 bsum=bsum-bx+sx; 49 } 50 } 51 mid[i][j]=bsum-big.top()*big.size()+big.top()*small.size()-ssum; 52 } 53 } 54 for(int i=1,x,y;i<=m;i++){ 55 x=read();y=read(); 56 ans-=mid[x][y]; 57 } 58 printf("%lld",ans); 59 return 0; 60 }
不要问我为什么用负数更新答案。
1209. 拉力赛 (Standard IO)
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSet倍增。
注意判一下深度啊。
1 #include<bits/stdc++.h> 2 using namespace std; 3 inline int read(){ 4 int x=0,f=1; 5 char c=getchar(); 6 while(!isdigit(c)){ 7 if(c=='-') f=-1; 8 c=getchar(); 9 } 10 while(isdigit(c)){ 11 x=(x<<1)+(x<<3)+(c^48); 12 c=getchar(); 13 } 14 return x*f; 15 } 16 const int N=1e4+10; 17 const int M=1e5+10; 18 int n,m,cnt; 19 long long ans1,ans2; 20 int f[N][25],head[M<<1],dep[N],det[N]; 21 struct edge{ 22 int to,next,w; 23 }e[M<<1]; 24 void addedge(int from,int to,int w){ 25 e[++cnt]=(edge){to,head[from],w}; 26 head[from]=cnt; 27 } 28 void dfs(int u,int fa){ 29 f[u][0]=fa; 30 det[u]=det[fa]+1; 31 for(int i=head[u];i;i=e[i].next){ 32 int v=e[i].to,w=e[i].w; 33 if(v==fa) continue; 34 dep[v]=dep[u]+w; 35 dfs(v,u); 36 } 37 } 38 int main(){ 39 // freopen("data2.in","r",stdin); 40 n=read();m=read(); 41 for(int i=1,x,y,z;i<n;i++){ 42 x=read();y=read();z=read(); 43 addedge(x,y,z); 44 addedge(y,x,z); 45 } 46 dfs(1,0); 47 for(int j=1;j<=20;j++){ 48 for(int i=1;i<=n;i++){ 49 f[i][j]=f[f[i][j-1]][j-1]; 50 } 51 } 52 for(register int i=1,x_,y_;i<=m;i++){ 53 x_=read();y_=read(); 54 int x=x_,y=y_; 55 if(det[x]>det[y]) continue; 56 int j=20; 57 for(int j=20;j>=0;j--){ 58 if(det[f[y][j]]>=det[x]) y=f[y][j]; 59 } 60 if(x==y){ 61 ans1++; 62 ans2+=dep[y_]-dep[x_]; 63 } 64 } 65 printf("%lld %lld",ans1,ans2); 66 return 0; 67 }
1210. 舞台设置 (Standard IO)
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSetdp题。
设
f[i][j][l][r]表示第i行,此时放了j个矩形,在区间[l,r]放矩形的最大面积。
g[i][j][l][r]表示第i行,此时放了j个矩形,在区间(l,r)放矩形的最大面积。
转移:
g[i][j][l][r]=max(g[i][j][l+1][r],g[i][j][l][r-1],f[i][j][l+1][r-1])
f[i][j][l][r]=max(f[i-1][j][l][r],g[i-1][j-1][l][r])+r-l+1或0(看这一行l到r是否都为0).
滚动一下即可AC。
注意枚举顺序。
1 #include<bits/stdc++.h> 2 using namespace std; 3 int read(){ 4 int x=0,f=1; 5 char c=getchar(); 6 while(!isdigit(c)){ 7 if(c=='-') f=-1; 8 c=getchar(); 9 } 10 while(isdigit(c)){ 11 x=(x<<1)+(x<<3)+(c^48); 12 c=getchar(); 13 } 14 return x*f; 15 } 16 const int N=110; 17 int n,m,h,ans; 18 bool a[N][N]; 19 int s[N][N]; 20 int f[2][25][N][N],g[2][25][N][N]; 21 int main(){ 22 n=read();m=read();h=read(); 23 for(int i=1;i<=n;i++){ 24 for(int j=1;j<=m;j++){ 25 a[i][j]=read(); 26 s[i][j]=s[i][j-1]+a[i][j]; 27 } 28 } 29 for(int i=1;i<=n;i++){ 30 int p=i%2; 31 for(int j=1;j<=h;j++){ 32 for(int l=m;l>=1;l--){ 33 for(int r=l;r<=m;r++){ 34 if(r-l+1>=3) g[p][j][l][r]=max(g[p][j][l+1][r],max(g[p][j][l][r-1],f[p][j][l+1][r-1])); 35 36 if((s[i][r]-s[i][l-1]==0)&&(j==1||g[p^1][j-1][l][r]>0)){ 37 38 f[p][j][l][r]=max(f[p^1][j][l][r],g[p^1][j-1][l][r])+r-l+1; 39 if(j==h) ans=max(ans,f[p][j][l][r]); 40 41 } 42 else f[p][j][l][r]=0; 43 44 // if(i==1&&j==1&&l==5&&r==5){ 45 // cout<<g[p][j][l][r]<<endl; 46 // } 47 } 48 } 49 } 50 } 51 printf("%d",ans); 52 return 0; 53 }