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 int
using 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 15050000
using 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出题人!!!
重要的事情说三遍…