题目传送门:http://www.oj.swust.edu.cn/contest/show/1160
这是一道dp。我们假设这n个人按照水平排成一排, 可以很容易想到用dp[i][j]表示: 排到第第i个位置的人面向左边的是第j个部位的总方案数。可以有转移
dp[i][j]+=dp[i-1][k] ( 只要k和j 不发生冲突就可以转移 )。总复杂度(O(16n))
AC 代码。
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include <time.h> #define debug using namespace std; const int inf = 0x3fffffff; const int mmax = 100010; const int mod = 522462628; int dir[mmax]; int dp[mmax][5]; int main() { int n; #ifdef debug freopen("in.txt","r",stdin); #endif while(cin>>n) { for(int i=1;i<=n;i++) scanf("%d",&dir[i]); memset(dp,0,sizeof dp); dp[1][1]=dp[1][2]=dp[1][3]=dp[1][4]=1; for(int i=2;i<=n;i++) { for(int j=1;j<=4;j++) { for(int k=1;k<=4;k++) { if(k==2 && abs(j-dir[i-1])==2 ) continue; if(j==4 && k==dir[i]) continue; dp[i][j]+=dp[i-1][k]; dp[i][j]%=mod; } } } int ans=0; for(int i=1;i<=4;i++) { ans+=dp[n][i]; ans%=mod; } cout<<ans<<endl; } return 0; }
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include <time.h> #include <map> #define debug using namespace std; const int inf = 0x3fffffff; const int mmax = 1010; struct edge { int st,en; int len,cost; bool operator < (const edge &a) const { if(len==a.len) return cost<a.cost; return len<a.len; } }E[10010]; map<string,int>q; bool ok(int x) { while(x) { if(x%10 == 9) return 0; x/=10; } return 1; } int fa[mmax]; int find(int x) { if(x==fa[x]) return x; return fa[x]=find(fa[x]); } int main() { #ifdef debug freopen("in.txt","r",stdin); #endif int n,m,len,cost,cnt,num; string u,v; while(cin>>n>>m) { q.clear(); cnt=num=0; for(int i=0;i<m;i++) { cin>>u>>v>>len>>cost; if(!q.count(u)) q[u]=++cnt; if(!q.count(v)) q[v]=++cnt; if(ok(len) && ok(cost)) { E[num].st=q[u]; E[num].en=q[v]; E[num].len=len; E[num].cost=cost; num++; } } for(int i=1;i<=n;i++) fa[i]=i; sort(E,E+num); len=0,cost=0; for(int i=0;i<num;i++) { int u=find(E[i].st); int v=find(E[i].en); if(u!=v) { fa[u]=v; len+=E[i].len; cost+=E[i].cost; } } cnt = 0; for(int i=1;i<=n;i++) { if(find(i)==i) cnt++; } if(cnt>=2) puts("Don't touch me!"); else cout<<"totlen: "<<len<<" mincost: "<<cost<<endl; } return 0; }
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<queue> #define debug using namespace std; const int mmax = 1000010; int num[mmax],c[mmax]; int sum[50010]; bool isprime[mmax]; void pre()//nlgn的预处理方法 { memset(isprime,1,sizeof isprime); num[1]=0; isprime[1]=0; for(int i=2;i<mmax;i++) { if(isprime[i]) { for(int j=2*i;j<mmax;j+=i) { isprime[j]=0; c[j]=i; } } } for(int i=2;i<mmax;i++) { if(isprime[i]) num[i]=1; else num[i]=num[i/c[i]]+1; } } int ff(int x)//暴力质因子分解 { int cnt; for(int i=2;i*i<=x;i++) { while(x%i==0) { cnt++; x/=i; } } if(x>1) cnt++; return cnt; } int main() { int n,q; #ifdef debug freopen("in.txt","r",stdin); #endif pre(); while(cin>>n>>q&& n+q) { sum[0]=0; for(int i=1;i<=n;i++) { int x; scanf("%d",&x); sum[i]=sum[i-1]+num[x];// +ff(x) 为暴力 } while(q--) { int l,r; scanf("%d %d",&l,&r); printf("%d\n",sum[r]-sum[l-1]); } } return 0; }
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define debug bool flag[10005]; int s[10005]; int main() { #ifdef debug freopen("in.txt","r",stdin); #endif int n,m; while(~scanf("%d%d",&n,&m)) { memset(flag,false,sizeof(flag)); for(int i=0;i<m;i++) { scanf("%d",&s[i]); flag[s[i]]=true; } sort(s,s+m); int ans=0; for(int i=0;i<m;i++) { bool k=false; for(int j=s[i]+1;j<=n*m;j++) { if(!flag[j]) { k=true; flag[j]=true; break; } } if(!k) ans++; } printf("%d\n",ans); } return 0; }
/* * Author: islands * Created Time: 2015/8/14 14:38:28 * File Name: stand.cpp */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include <time.h> #include <map> #define debug using namespace std; typedef long long LL; const int inf = 0x3fffffff; const int mmax = 110; bool G[mmax][mmax]; int card1[mmax]; int card2[mmax]; map<int,int>q; int link[mmax]; bool vis[mmax]; bool match(int x,int n) { for(int i=0;i<n;i++) { if( G[x][i] && !vis[i]) { vis[i]=1; if(link[i]==-1 || match(link[i],n)) { link[i]=x; return 1; } } } return 0; } int hungury(int n) { int cnt=0; memset(link,-1,sizeof link); for(int i=0;i<n;i++) { memset(vis,0,sizeof vis); if(match(i,n)) cnt++; } return cnt; } int main() { #ifdef debug freopen("in.txt","r",stdin); #endif int n,m; while(cin>>n>>m) { memset(G,0,sizeof G); q.clear(); for(int i=0;i<m;i++) { scanf("%d",&card1[i]); q[card1[i]]=1; } int cnt=0; for(int i=n*m;i>=1;i--) { if(!q.count(i) && cnt<m) card2[cnt++]=i; } for(int i=0;i<m;i++) { for(int j=0;j<m;j++) { if(card1[i]<card2[j]) G[i][j]=1; } } printf("%d\n",m-hungury(m)); } return 0; }
/* * Author: islands * Created Time: 2015/8/14 14:38:28 * File Name: stand.cpp */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include <time.h> #include <map> #define debug using namespace std; typedef long long LL; const int inf = 0x3fffffff; const int mmax = 110; const int mod = 10007; int Pow_mod(int x,int y) { int res=1; for(;y;y/=2) { if(y&1) res=res*x%mod; x=x*x%mod; } return res; } int main() { #ifdef debug freopen("in.txt","r",stdin); #endif int n,m; while(cin>>n>>m) { int ans=Pow_mod(m,n-1); ans*=n; ans%=mod; ans*=(m-1); ans%=mod; cout<<ans<<endl; } return 0; }
/* * Author: islands * Created Time: 2015/8/14 14:38:28 * File Name: stand.cpp */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include <time.h> #define debug using namespace std; typedef long long LL; const int inf = 0x3fffffff; const int mmax = 100010; LL sum[31][2]; int Size[31]; int main() { #ifdef debug freopen("in.txt","r",stdin); #endif int k,x; while(cin>>k) { for(int i=1;i<=k;i++) { scanf("%d",&Size[i]); sum[i][0]=sum[i][1]=0; for(int j=1;j<=Size[i];j++) { scanf("%d",&x); sum[i][0]+=x; sum[i][1]+=x*j; } } printf("0\n"); for(int i=2;i<=k;i++) { LL ans=1LL*Size[i-1]*sum[i][1]+1LL*Size[i]*sum[i-1][1]; ans+=1LL*(Size[i]+1)*Size[i]/2*sum[i-1][0]; ans+=1LL*(Size[i-1]+1)*Size[i-1]/2*sum[i][0]; printf("%lld\n",ans); } } return 0; }
/* * Author: islands * Created Time: 2015/8/13 21:49:13 * File Name: stand.cpp */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include <time.h> #define debug using namespace std; const int inf = 0x3fffffff; const int mmax = 300; int Photo[mmax][mmax]; int main() { #ifdef debug freopen("in.txt","r",stdin); #endif int n,m; while(~scanf("%d %d",&n,&m)) { for(int i=0;i<n;i++) for(int j=0;j<m;j++) scanf("%d",&Photo[i][j]); int q; cin>>q; while(q--) { int d,k; cin>>d>>k; if(d==0) { for(int i=0;i<(n/k);i++) { for(int j=0;j<(m/k);j++) { printf("%d%c",Photo[i*k][j*k],(j==(m/k)-1)?'\n':' '); } } } else { for(int i=0;i<n*k;i++) { for(int j=0;j<m*k;j++) { printf("%d%c",Photo[i/k][j/k],(j==m*k-1)?'\n':' '); } } } } } return 0; }
求区间内最大值的位置,取最靠左的那个的位置。单点修改。
思路:用线段树维护区间内的最大值和最大值最靠左的位置,记录2个值,一个记录最大值,另一个几率对应位置。实际上只用开一个值,只用记录位子即可,因为位置包含着最大值。
/* * Author: islands * Created Time: 2015/8/14 14:38:28 * File Name: stand.cpp */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include <time.h> #define debug using namespace std; const int inf = 0x3fffffff; const int mmax = 100010; int A[mmax]; struct node { int l,r; int pos,max_val; int mid() { return (l+r)>>1; } }T[4*mmax]; void push_up(node &fa,node &ls,node& rs) { fa.l=ls.l,fa.r=rs.r; fa.max_val=max(ls.max_val,rs.max_val); if(fa.max_val==ls.max_val) { fa.pos=ls.pos; return ; } fa.pos=rs.pos; } void build(int id,int l,int r) { T[id].l=l,T[id].r=r; if(l==r) { T[id].pos=l; T[id].max_val=A[l]; return ; } int mid=T[id].mid(); build(id<<1,l,mid); build(id<<1|1,mid+1,r); push_up(T[id],T[id<<1],T[id<<1|1]); } void update(int id,int pos,int val) { if(T[id].l==T[id].r) { T[id].max_val=val; return ; } int mid=T[id].mid(); if(mid>=pos) update(id<<1,pos,val); else update(id<<1|1,pos,val); push_up(T[id],T[id<<1],T[id<<1|1]); } node query(int id,int l,int r) { if(l<= T[id].l && T[id].r <=r) return T[id]; int mid=T[id].mid(); node tmp[3]; int t=0; if(mid>=l) tmp[1]=query(id<<1,l,r),t++; if(mid<r) tmp[2]=query(id<<1|1,l,r),t+=2; if(t<3) return tmp[t]; push_up(tmp[0],tmp[1],tmp[2]); return tmp[0]; } int main() { #ifdef debug freopen("in.txt","r",stdin); #endif int t,n,q; int op,a,b; cin>>t; while(t--) { scanf("%d %d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&A[i]); build(1,1,n); while(q--) { scanf("%d %d %d",&op,&a,&b); if(op==1) { node ans=query(1,a,b); printf("%d\n",ans.pos); } else update(1,a,b); } } return 0; }