NOIP 2013 提高组 合集
D1 T1 转圈游戏
快速幂裸题
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; ll mod; ll qpow(ll x,ll y) { ll ans=1; while(y) { if(y&1) ans=(ans*x)%mod; y>>=1; x=(x*x)%mod; } return ans; } int main() { ll m,k,x; cin >> mod >> m >> k >> x ; // printf("%lld ",qpow(10,10)); printf("%lld ",(x+qpow(10,k)%mod*m%mod)%mod); return 0; }
D1 T2 火柴排队
我们显然可以固定一个序列,因为我们可以通过相对的交换来等价地达到目的。
所以只需要求离散化后的逆序对即可。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define mod 99999997 #define N 100010 using namespace std; typedef long long ll; ll tree[N<<1],n; inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;} ll rd() {ll x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;} struct Node { ll len; int id,now; }a[N],b[N]; inline bool cmp_len(const Node &x,const Node &y) {return x.len<y.len;} // inline bool cmp_id(const Node &x,const Node &y) {return x.id<y.id;} inline int lowbit(int x) {return x&(-x);} void update(int x) { for(int i=x;i>=1;i-=lowbit(i)) (tree[i]+=1)%=mod; } ll query(int x) { ll ans=0; for(int i=x;i<=n+1;i+=lowbit(i)) (ans+=tree[i])%=mod; return ans; } int main() { n=rd(); for(int i=1;i<=n;i++) { a[i].len=rd(); a[i].id=i; } for(int i=1;i<=n;i++) { b[i].len=rd(); b[i].id=i; } sort(a+1,a+n+1,cmp_len); sort(b+1,b+n+1,cmp_len); // puts("Fuck"); for(int i=1;i<=n;i++) printf("%lld ",b[i].id); puts(""); for(int i=1;i<=n;i++) { a[a[i].id].now=b[i].id; } // for(int i=1;i<=n;i++) printf("%d ",a[i].now); puts(""); ll ans=0; for(int i=1;i<=n;i++) { update(a[i].now); (ans+=query(a[i].now+1))%=mod; } printf("%lld ",ans); return 0; }
D1 T3 运输计划
离线+树剖+线段树+并查集
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define N 100010 using namespace std; struct Node { int x,y,z; }a[N]; int n,m; int head[N],to[N<<1],val[N<<1],nxt[N<<1],tot,F[N],dep[N],f[N][20],g[N][20]; bool vis[N]; inline bool cmp(const Node &x,const Node &y) {return x.z>y.z;} inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;} int rd() {int x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;} inline void add(int x,int y,int z) {to[++tot]=y; val[tot]=z; nxt[tot]=head[x]; head[x]=tot;} int find(int x) {return F[x]==x?x:F[x]=find(F[x]);} void dfs(int pos,int fa) { f[pos][0]=fa; dep[pos]=dep[fa]+1; for(int i=1;i<=18;i++) f[pos][i]=f[f[pos][i-1]][i-1]; for(int i=head[pos];i;i=nxt[i]) if(to[i]!=fa) { dfs(to[i],pos); } } void dfs2(int pos,int fa) { for(int i=head[pos];i;i=nxt[i]) if(to[i]!=fa) { g[to[i]][0]=val[i]; for(int j=1;j<=18;j++) g[to[i]][j]=min(g[to[i]][j-1],g[f[to[i]][j-1]][j-1]); dfs2(to[i],pos); } } int calc(int x,int y) { // printf("%d %d ",x,y); int ans=0x7f7f7f7f; if(dep[x]<dep[y]) swap(x,y); // printf("%d %d %d ",x,y,ans); for(int i=18;~i;i--) { // printf("%d %d %d ",x,y,ans); if(dep[f[x][i]]>=dep[y]) ans=min(ans,g[x][i]),x=f[x][i]; } if(x==y) return ans; for(int i=18;~i;i--) { // printf("%d %d %d ",x,y,ans); if(f[x][i]!=f[y][i]) ans=min(ans,min(g[x][i],g[y][i])),x=f[x][i],y=f[y][i]; } // printf("%d %d %d ",x,y,ans); return min(ans,min(g[x][0],g[y][0])); } inline bool merge(int x,int y) { x=find(x); y=find(y); if(x==y) return true; F[x]=y; return false; } void test() { for(int i=1;i<=3;i++) { for(int j=0;j<=18;j++) printf("%d ",g[i][j]); puts(""); } } int main() { memset(g,0x7f,sizeof g); n=rd(),m=rd(); int x,y; for(int i=1;i<=n;i++) F[i]=i; for(int i=1;i<=m;i++) a[i].x=rd(),a[i].y=rd(),a[i].z=rd(); sort(a+1,a+m+1,cmp); for(int i=1;i<=m;i++) { if(!merge(a[i].x,a[i].y)) { // printf("Shit %d %d %d ",a[i].x,a[i].y,a[i].z); add(a[i].x,a[i].y,a[i].z); add(a[i].y,a[i].x,a[i].z); } } // printf("%d ",find(1)); for(int i=1;i<=n;i++) { x=find(i); if(!vis[x]) dfs(x,x),dfs2(x,x),vis[x]=1; } // test(); int q=rd(); for(int i=1;i<=q;i++) { x=rd(),y=rd(); if(find(x)!=find(y)) {puts("-1"); continue;} printf("%d ",calc(x,y)); } return 0; }
D2 T1 积木大赛
sb题
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int main() { int n,a; cin >> n ; int last=0,ans=0; for(int i=1;i<=n;i++) { scanf("%d",&a); if(a>last) ans += (a-last); last=a; } cout << ans << endl ; return 0; }
D2 T2 花匠
dp裸题
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 100010 int a[N],f[N][2]; inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;} int rd() {int x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;} int main() { int n=rd(); for(int i=1;i<=n;i++) a[i]=rd(); f[1][0]=f[1][1]=1; for(int i=2;i<=n;i++) { if(a[i]>a[i-1]) f[i][0]=f[i-1][1]+1; else f[i][0]=f[i-1][0]; if(a[i]<a[i-1]) f[i][1]=f[i-1][0]+1; else f[i][1]=f[i-1][1]; } printf("%d ",max(f[n][0],f[n][1])); return 0; }
D2 T3 华容道
挖坑代填