【Training Contest】2016.03.08
aw。。。这好像是停课以来第一次考试哎。。。蒟蒻滚粗啦
T1.变幻莫测的数列
迷之卡常QAQ;不过窝竟然卡了90分。。。憋人都卡了85。。好神奇啊
听说卡常技巧。。。计算时暴力int转longlong,用int记录。。。反复定义的变量改全局。。。读入优化QAQ
考试时候写了两个程序,分块和线段树。。显然线段树更快一点
分块
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> #define mod 1000000007ll #define LL long long #define NN 500010 using namespace std; int n,q,cnt,block,belong[NN],st[NN],x; struct REC { LL a,b; }s[NN],c[NN]; LL ans; char ch,chh[55]; bool f; void readl(LL &x){ for(ch=getchar();ch<'0'||ch>'9';ch=getchar()); for(x=0;ch>='0';ch=getchar())x=x*10+ch-'0'; } void read(int &x){ for(ch=getchar();ch<'0'||ch>'9';ch=getchar()); for(x=0;ch>='0';ch=getchar())x=x*10+ch-'0'; } void Build(int xx) { c[xx].a=1ll,c[xx].b=0ll; for (int j=st[xx];j<=st[xx+1]-1;++j) c[xx].a=(c[xx].a*s[j].a)%mod, c[xx].b=((c[xx].b*s[j].a)%mod+s[j].b)%mod; } int main() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); read(n), read(q); for (int i=1;i<=n;++i) readl(s[i].a), readl(s[i].b); cnt=(int) sqrt(n); for (int i=1;i<=n;++i) belong[i]=(i-1)/cnt+1; block=belong[n]; block=(n-1)/cnt+1; for (int i=1;i<=block;++i) st[i]=(i-1)*cnt+1; st[block+1]=n+1; for (int i=1;i<=block;++i) Build(i); while (q--) { scanf("%s",chh); if (chh[0]=='Q') { read(x); ans=1ll; for (int i=1;i<belong[x];++i) ans=(ans*c[i].a%mod+c[i].b)%mod; for (int i=st[belong[x]];i<=x;++i) ans=(ans*s[i].a%mod+s[i].b)%mod; printf("%lld\n",ans); } else read(x), readl(s[x].a), readl(s[x].b), Build(belong[x]); } fclose(stdin); fclose(stdout); return 0; }
线段树(%%%把线段树写RE的线段树大师(大雾
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> #define mod 1000000007ll #define LL long long #define NN 500010 using namespace std; int n,q,x; LL ans; struct REC { int l,r,mid; LL a,b; }tree[NN*6]; struct NODE { LL a,b; }s[NN]; char ch,chh[55]; void readl(LL &x){ for(ch=getchar();ch<'0'||ch>'9';ch=getchar()); for(x=0;ch>='0';ch=getchar())x=x*10+ch-'0'; } void read(int &x){ for(ch=getchar();ch<'0'||ch>'9';ch=getchar()); for(x=0;ch>='0';ch=getchar())x=x*10+ch-'0'; } void Build(int p,int x,int y) { tree[p].l=x, tree[p].r=y, tree[p].mid=(x+y)>>1; if (x==y) { tree[p].a=s[x].a%mod, tree[p].b=s[x].b%mod; return; } Build(p<<1,x,tree[p].mid), Build(p<<1|1,tree[p].mid+1,y); tree[p].a=tree[p<<1].a*tree[p<<1|1].a%mod; tree[p].b=(tree[p<<1].b*tree[p<<1|1].a%mod+tree[p<<1|1].b)%mod; } void Change(int p,int x) { if (tree[p].l==x && tree[p].r==x) tree[p].a=s[x].a, tree[p].b=s[x].b; else { if (x<=tree[p].mid) Change(p<<1,x); else Change(p<<1|1,x); tree[p].a=tree[p<<1].a*tree[p<<1|1].a%mod; tree[p].b=(tree[p<<1].b*tree[p<<1|1].a%mod+tree[p<<1|1].b)%mod; } } void Query(int p,int x,int y) { if (tree[p].l==x && tree[p].r==y) { ans=((ans*tree[p].a)%mod+tree[p].b)%mod; return; } else { if (y<=tree[p].mid) Query(p<<1,x,y); else Query(p<<1,x,tree[p].mid), Query(p<<1|1,tree[p].mid+1,y); } } int main() { freopen("sequence.in","r",stdin); freopen("sequence.out","w",stdout); read(n), read(q); for (int i=1;i<=n;++i) readl(s[i].a), readl(s[i].b); Build(1,1,n); while (q--) { scanf("%s",chh); if (chh[0]=='Q') { read(x); if (x==0) { puts("1"); continue;} ans=1ll; Query(1,1,x); printf("%lld\n",ans); } else { read(x), readl(s[x].a), readl(s[x].b); Change(1,x); } } fclose(stdin); fclose(stdout); return 0; }
T2.微型加密系统
考试骗了20分滚粗走人
骗分程序(Floyd直接输出答案。。。听说两边spfa有40分
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cstdlib> using namespace std; int n,m,x,y,a[110][110]; int main() { freopen("microc.in","r",stdin); freopen("microc.out","w",stdout); while (scanf("%d%d",&n,&m)) { if (n==0 && m==0) break; memset(a,0x3f,sizeof(a)); for (int i=1;i<=m;++i) scanf("%d%d",&x,&y), a[x][y]=1; for (int k=1;k<=n;++k) for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) a[i][j]=min(a[i][j],a[i][k]+a[k][j]); if (a[1][2]==0x3f3f3f3f || a[2][1]==0x3f3f3f3f) { puts("Impossible"); continue; } printf("%d\n",a[1][2]+a[2][1]); } fclose(stdin); fclose(stdout); return 0; }
新鲜出炉的FLOYD&SPFA
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define NN 110 using namespace std; int n,m,x,y,dis[NN][NN],a[NN][NN]; bool vis[NN][NN]; struct REC { int x,y; }; queue<REC> que; int main() { freopen("microc.in","r",stdin); freopen("microc.out","w",stdout); while (scanf("%d%d",&n,&m)>0 && n) { memset(a,0x3f,sizeof(a)); for (int i=1;i<=n;++i) a[i][i]=0; for (int i=1;i<=m;++i) scanf("%d%d",&x,&y), a[x][y]=1; for (int k=1;k<=n;++k) for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) a[i][j]=min(a[i][j],a[i][k]+a[k][j]); memset(dis,0x3f,sizeof(dis)); REC tmp,tmpp; tmp.x=1,tmp.y=1; dis[1][1]=1; vis[1][1]=1; que.push(tmp); while (!que.empty()) { tmp=que.front(); que.pop(); for (int i=1;i<=n;++i) { int j=(i!=tmp.x)&&(i!=tmp.y); if (a[tmp.x][i]==1 && dis[i][tmp.y]>dis[tmp.x][tmp.y]+j) { dis[i][tmp.y]=dis[tmp.x][tmp.y]+j; if (!vis[i][tmp.y]) vis[i][tmp.y]=1, tmpp.x=i, tmpp.y=tmp.y, que.push(tmpp); } if (a[i][tmp.y]==1 && dis[tmp.x][i]>dis[tmp.x][tmp.y]+j) { dis[tmp.x][i]=dis[tmp.x][tmp.y]+j; if (!vis[tmp.x][i]) vis[tmp.x][i]=1, tmpp.x=tmp.x, tmpp.y=i, que.push(tmpp); } } if (tmp.x!=tmp.y) { if (dis[tmp.y][tmp.x]>dis[tmp.x][tmp.y]+a[tmp.x][tmp.y]-1) { dis[tmp.y][tmp.x]=dis[tmp.x][tmp.y]+a[tmp.x][tmp.y]-1; if (!vis[tmp.y][tmp.x]) vis[tmp.y][tmp.x]=1, tmpp.x=tmp.y, tmpp.y=tmp.x, que.push(tmpp); } } vis[tmp.x][tmp.y]=0; } if(dis[2][2]==0x3f3f3f3f) puts("Impossible");else printf("%d\n",dis[2][2]); } fclose(stdin); fclose(stdout); return 0; }
T3.俄罗斯方块问题
迷之贪心
听说有两行程序
但蒟蒻太弱了只能码线段树了
线段树
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <algorithm> #define MM 4000010 using namespace std; int n,m,x,y; struct REC { int l,r,v,mid; }tree[MM]; int ans=0; void read(int &x) { char c;for(x=0,c=getchar();c<'0'&&c>'9';c=getchar()); for(;c>='0'&&c<='9';x=x*10+c-'0',c=getchar()); } void Build(int p,int x,int y) { tree[p].l=x, tree[p].r=y, tree[p].v=0, tree[p].mid=(x+y)>>1; if (x==y) return; Build(p<<1,x,tree[p].mid), Build(p<<1|1,tree[p].mid+1,y); } void Add(int p,int x,int y) { if (tree[p].l==x && tree[p].r==y) tree[p].v++; else { if (y<=tree[p].mid) Add(p<<1,x,y); else if (x>tree[p].mid) Add(p<<1|1,x,y); else Add(p<<1,x,tree[p].mid), Add(p<<1|1,tree[p].mid+1,y); } } void Query(int p,int x,int y,int v) { if (x==y) {if (v+tree[p].v>ans) ans=v+tree[p].v; return;} Query(p<<1,x,tree[p].mid,tree[p].v+v); Query(p<<1|1,tree[p].mid+1,y,tree[p].v+v); } int main() { freopen("tetris.in","r",stdin); freopen("tetris.out","w",stdout); read(n), read(m); Build(1,1,m-1); for(int i=1;i<=n;++i) { read(x), read(y); Add(1,x,y-1); } Query(1,1,m-1,0); printf("%d\n",ans); fclose(stdin); fclose(stdout); return 0; }
迷之压行
#include<cstdio> int b[1000010],n,m,l,r,a,t,i;int main(){for(scanf("%d%d",&n,&m),i=1;i<=n;i++)scanf("%d%d",&l,&r),b[l]++,b[r]--;for(i=1;i<=m;i++)a=a>(t+=b[i])?a:t;printf("%d",a);}