CQOI2016滚粗记

来源:互联网 发布:菜鸟网络工作怎么样 编辑:程序博客网 时间:2024/05/05 10:13

day0
上去试机发现鼠标是坏的,旁边是巴蜀的大牛和教师机…
随手敲了一个树剖和Pollard_rho,顺路用批处理对拍了一下,然后想去交一发意外的发现竟然木有网….

晚上复习了一下板子…然后写得有点兴奋了就睡不着辣…

day1
上歌乐山的时候还在下雨…
然后我7点就悠悠的到了门口…然后就在外面晃荡了40多分钟…
8点过就进了考场,发现解压密码一点都不好玩…

看到T1的时候心里一阵窃喜,嘿嘿我做过bzoj2229的,不就是一道分治最小割的水题吗…30分钟敲完就写了一个对拍,拍了一个小时木有错就默默的水过辣…

#include <iostream>#include <cstdio>#include <algorithm>#define MAXN 855#define MAXM 20005#define inf 0x3f3f3f3f#define min(a,b) ((a)<(b)?(a):(b))using namespace std;struct node{    int v, w, next;}edge[MAXM];int adj[MAXN], pos, n, m, a[MAXN], tmp[MAXN], T, S;int d[MAXN], vd[MAXN], road[MAXN*MAXN], cnt;inline void add(int u,int v,int w){    edge[pos].v=v, edge[pos].w=w, edge[pos].next=adj[u];    adj[u]=pos;    ++pos;    edge[pos].v=u, edge[pos].w=w, edge[pos].next=adj[v];    adj[v]=pos;    ++pos;}int aug(int u,int augco){    if(u==T)return augco;    int augc=augco, mind=n, delta, v;    for(int p=adj[u];~p;p=edge[p].next)        if(edge[p].w>0)        {            v=edge[p].v;            if(d[v]+1==d[u])            {                delta=aug(v,min(augc,edge[p].w));                edge[p].w-=delta, augc-=delta, edge[p^1].w+=delta;                if(!augc||d[S]>=n)return augco-augc;            }            mind=min(mind,d[v]);        }    if(augco==augc)    {        if(!--vd[d[u]])d[S]=n;        else ++vd[d[u]=mind+1];    }    return augco-augc;}int q[MAXM], head, tail;bool vis[MAXN], in[MAXN];void bfs(){    head=tail=0;    q[++tail]=T, d[T]=0;    int u, v;    while(head<tail)    {        u=q[++head], in[u]=0;        for(int p=adj[u];~p;p=edge[p].next)            if(edge[p^1].w>0&&d[v=edge[p].v]>d[u]+1)            {                d[v]=d[u]+1;                if(!in[v])q[++tail]=v, in[v]=1;            }    }}int isap(){    for(int p=0;p<pos;p+=2)        edge[p].w=edge[p^1].w=(edge[p].w+edge[p^1].w)/2;    for(int i=1;i<=n;++i)d[i]=inf, vd[i]=0, vis[i]=0;    bfs();    for(int i=1;i<=n;++i)        if(d[i]!=inf)++vd[d[i]];    int ans=0;    while(d[S]<n)        ans+=aug(S,inf);    return ans;}void dfs(int u){    vis[u]=1;    for(int p=adj[u], v;~p;p=edge[p].next)        if(edge[p].w>0&&!vis[v=edge[p].v])            dfs(v);}void solve(int l,int r){    if(l==r)return;    S=a[l], T=a[r];    int ans=isap();    road[++cnt]=ans;    dfs(S);    int p1=l, p2=r;    for(int i=l;i<=r;++i)        if(vis[a[i]])tmp[p1++]=a[i];        else tmp[p2--]=a[i];    for(int i=l;i<=r;++i)        a[i]=tmp[i];    solve(l,p1-1), solve(p2+1,r);}int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;++i)adj[i]=-1, a[i]=i;    int u, v, w;    while(m--)    {        scanf("%d%d%d",&u,&v,&w);        add(u,v,w);    }    solve(1,n);    sort(road+1,road+cnt+1);    int ans=1;    for(int i=2;i<=cnt;++i)        if(road[i]!=road[i-1])++ans;    printf("%d\n",ans);    return 0;}

T2 不会的说…就默默滴写了个大暴力…外加一个分治乱写一共骗了40分…
附上之后写的题解… 题解链接

T3 一眼看穿是一个数位DP,然后…我TM搞了两个多小时都木有搞出来,真是太垃圾辣…

day1就这样160滚粗辣…
晚上就默默滴敲了几个计算几何和数学的板子…

day2
早上继续雨蒙蒙…
怀着对滚粗的美好向往,我默默滴进入机房…
然后…

T1 TM不就是想考Pollard_rho吗…不虚…
30分钟敲完,又写了一个对拍,没问题…
恩,100分稳稳滴…

#include <iostream>#include <cstdio>#include <algorithm>#define abs(a) ((a)>0?(a):-(a))#define LL long long intusing namespace std;LL mul(LL a,LL pos,LL mod){    LL ans=0;    for(;pos;pos>>=1)    {        if(pos&1){ans+=a;if(ans>=mod)ans-=mod;}        a+=a;if(a>=mod)a-=mod;    }    return ans;}LL power(LL a,LL pos,LL mod){    LL ans=1;    for(;pos;pos>>=1, a=mul(a,a,mod))        if(pos&1)ans=mul(ans,a,mod);    return ans;}bool Miller_Rabin(LL n){    if(n==2||n==3)return 1;    if(!(n&1))return 0;    LL m=n-1, a, tmp, ans;    int cnt=0;    while(!(m&1))m>>=1, ++cnt;    for(int i=0;i<20;++i)    {        a=rand()%(n-1)+1;        tmp=power(a,m,n);        for(int j=0;j<cnt;++j)        {            ans=mul(tmp,tmp,n);            if(ans==1)            {                if(tmp!=1&&tmp!=n-1)return 0;                break;            }            tmp=ans;        }        if(ans!=1)return 0;    }    return 1;}LL gcd(LL a,LL b){    if(!b)return a;    return gcd(b,a%b);}LL work(LL a,LL b){    LL cnt=0, k=2, x0=rand()%a, y=x0, d;    while(1)    {        ++cnt;        x0=(mul(x0,x0,a)+b)%a;        d=gcd(abs(y-x0),a);        if(d!=1&&d!=a)return d;        if(y==x0)return a;        if(cnt==k)k+=k, y=x0;    }}LL fac[105];int tot;void dfs(LL n){    if(Miller_Rabin(n)){fac[++tot]=n;return;}    LL p=n;    while(p>=n)p=work(p,rand()%(n-1)+1);    dfs(p), dfs(n/p);}void exgcd(LL a,LL b,LL &d,LL &x,LL &y){    if(!b)d=a, x=1, y=0;    else    {        exgcd(b,a%b,d,y,x);        y-=a/b*x;    }}LL ask_ni(LL a,LL b){    LL d, x, y;    exgcd(a,b,d,x,y);    LL mod=b/d;    return (x%mod+mod)%mod;}LL e, N, c;int main(){    cin>>e>>N>>c;    dfs(N);    LL r=(fac[1]-1)*(fac[2]-1);    LL d=ask_ni(e,r);    cout<<d<<' '<<power(c,d,N);    return 0;}

T2 一开始木有看懂题啊…
然后磨了半个小时,然后加了一点补充说明就看懂了。
不就是一个水水的01Trie吗,不虚200稳稳滴…

#include <iostream>#include <cstdio>#include <algorithm>#define MAXN 1000005#define MAXM 15050000using namespace std;char w;inline void GET(int &t){    t=0;    do w=getchar();while(w<'0'||w>'9');    do{t=t*10+w-'0';w=getchar();}while(w>='0'&&w<='9');}int tmp[MAXN], temp, len[MAXN];struct Trie{    int ch[MAXM][2], pos, id[MAXM];    inline void insert(char w[],int len,int d)    {        int p=0;        for(int i=1;i<=len;++i)            if(!ch[p][w[i]])p=ch[p][w[i]]=++pos;            else p=ch[p][w[i]];        if(!id[p])id[p]=d;    }    inline void query(char w[])    {        int p=0;        for(int i=1;i<33;++i)        {            if(ch[p][w[i]])p=ch[p][w[i]];            else return;            if(id[p])tmp[++temp]=id[p];        }    }}t;char s[36];int main(){    int n, u, a, b, cnt=0, ans, mv, tot;    char ask[10];    GET(n);    while(n--)    {        scanf("%s",ask);        if(ask[0]=='A')        {            ++cnt, tot=0;            for(int i=1;i<5;++i)            {                GET(u);                for(int j=7;~j;--j)                    if(u&(1<<j))s[++tot]=1;                    else s[++tot]=0;            }            GET(len[cnt]);            t.insert(s,len[cnt],cnt);        }        else        {            tot=0;            for(int i=1;i<5;++i)            {                GET(u);                for(int j=7;~j;--j)                    if(u&(1<<j))s[++tot]=1;                    else s[++tot]=0;            }            temp=0, t.query(s);            sort(tmp+1,tmp+temp+1);            GET(a), GET(b), ans=mv=0;            for(int i=1;i<=temp;++i)                if(mv<len[tmp[i]])                {                    mv=len[tmp[i]];                    if(tmp[i]>b)break;                    if(a<=tmp[i])++ans;                }            printf("%d\n",ans);        }    }    return 0;}

T3 一看,(⊙v⊙)嗯好像是一道赤裸裸数学题,然后就默默滴推了2个多小时,然后木有推出来,然后就写了一个大暴力,弃疗…

正解:大力出奇迹…我真是…

把128内的质数打出来,随便搞搞这个搞出来这个质数最多能被选多少次,然后枚举一个要选择的最大的质数,这样就可以枚举这个质数被选次数内的比这个质数小的所有质数了。就是个集合的无序拆分。
剪枝:10^14的第800000个伪光滑数一定比10^15的第800000个伪光滑数小,这样假设我们知道10^14的第800000个伪光滑数,这个数可以拿来剪枝,然后10^15的第800000个伪光滑数算起来就很快了,可以拿去剪10^16的第800000个伪光滑数。
by quack…
我就%%%%%%

day2 230彻底滚粗…

加上noip成绩默默滴排到了第8左右…
幸好noip考得好…
然后女生保护政策就默默滴拿了一个A类…
感觉不是很爽,毕竟D1T2出题人面向巴蜀选手出数据,居然让旋转卡壳和三分就这样水过辣,表示很不爽…
SB出题人!!!SB出题人!!!SB出题人!!!
重要的事情说三遍…

0 0
原创粉丝点击