ZF_20160614_计蒜客
来源:互联网 发布:linux 登录日志查询 编辑:程序博客网 时间:2024/06/15 21:31
初赛一 青云的机房组网方案
求所有互质节点距离和
1、树形dp
2、质因数的容斥原理
例如i为24,只需要考虑1,2,3,6
i为45,只需要考虑1,3,5,15
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#define ll long long#define clr(x,y) memset(x,y,sizeof x)using namespace std;ll pri[510],vis[510],lim=500,pnt;ll tag[510],tnt,F[510];vector<ll>Div[510],Mul[510];void dfs(ll cur,ll id,ll flag){ if(id>pnt)return; dfs(cur,id+1,flag); if(cur*pri[id]<=lim) { tag[++tnt]=cur*pri[id]; F[cur*pri[id]]=-flag; dfs(cur*pri[id],id+1,-flag); }}void getP(){ for(ll i=2;i<=lim;i++) { if(!vis[i]) { pri[++pnt]=i; for(ll j=2;i*j<=lim;j++)vis[i*j]=1; } } tag[++tnt]=1;F[1]=1; dfs(1,1,1); sort(tag+1,tag+tnt+1); for(ll i=1;i<=tnt;i++) { for(ll j=1;j*tag[i]<=lim;j++) { Div[j*tag[i]].push_back(tag[i]); Mul[tag[i]].push_back(j*tag[i]); } }}ll n,dat[10010],ans;ll tot[510],left[10010][510],right[10010][510];ll sum[10010][510];namespace G{ vector<ll>V[10010]; ll mx; void Init() { for(ll i=1;i<=n;i++)V[i].clear(); clr(tot,0);clr(left,0);clr(sum,0); ans=0;mx=0; } void dfs(ll u,ll fa) { left[u][dat[u]]++; ll len=V[u].size(); for(ll i=0;i<len;i++) { ll v=V[u][i]; if(v==fa)continue; dfs(v,u); for(ll j=1;j<=mx;j++)left[u][j]+=left[v][j]; } for(ll i=1;i<=tnt;i++) { for(int j=1;j*tag[i]<=lim;j++) sum[u][tag[i]]+=left[u][j*tag[i]]; } for(ll i=1;i<=mx;i++)right[u][i]=tot[i]-left[u][i]; for(ll i=1;i<=mx;i++) { ll siz=Div[i].size(); for(ll j=0;j<siz;j++) { ans+=sum[u][Div[i][j]]*F[Div[i][j]]*right[u][i]; } } } void Go() { while(~scanf("%lld",&n)) { Init(); for(ll i=1;i<=n;i++)scanf("%lld",&dat[i]),mx=mx>dat[i]?mx:dat[i],tot[dat[i]]++; for(ll i=1;i<n;i++) { ll x,y; scanf("%lld%lld",&x,&y); V[x].push_back(y);V[y].push_back(x); } dfs(1,-1); printf("%lld\n",ans); } }}int main(){ getP(); G::Go();}
初赛二 联想的显示屏校准
计算几何
初赛三 百度帐号的选取方案
输入用户名abc,如果重复就变成abcabc,求不重复时循环节最小是多少?
KMP
1、val[i][j] 从i到j的最大循环节
2、num[i][j] i开始循环节为j的子串有几个
3、sum[i][j] num数组的后缀和
#include<cstdio>#include<cstring>#include<algorithm>#define ll long long#define clr(x,y) memset(x,y,sizeof x)using namespace std;ll val[1010][1010],num[1010][1010],sum[1010][1010];namespace KMP{ ll nxt[100010]; ll gnt(char b[],ll lb) { for(ll i=0,j=nxt[0]=-1;i<lb;) { j==-1||b[i]==b[j]? nxt[++i]=++j:j=nxt[j]; } }};char c[1010];int main(){ while(~scanf("%s",c+1)) { ll len=strlen(c+1); clr(val,0); clr(num,0); clr(sum,0); for(ll i=1;i<=len;i++) { KMP::gnt(c+i,len+1-i); for(ll j=i;j<=len;j++) { val[i][j]=(j-i+1)%((j-i+1)-KMP::nxt[j-i+1])==0?(j-i+1)/((j-i+1)-KMP::nxt[j-i+1]):1; num[i][val[i][j]]++; } } for(ll i=len;i>0;i--) { for(ll j=1;j<=len;j++) sum[i][j]=sum[i+1][j]+num[i][j]; } ll ans=0; for(ll i=1;i<=len;i++) { for(ll j=i;j<=len;j++) ans+=sum[j+1][val[i][j]]; } printf("%lld\n",ans); }}
初赛四 遗失的支付宝密码
1、容斥 f(x)表示至少含有x个square的字符串的个数
结果为c1*m^1 + c2*m^2+ … + cn*m^n
2、打表 电脑大概需要跑20秒左右
3、要求前缀和,因为字符串长度要求不大于n,1,2也要算
4、用unsigned long long比较好
#include<cstdio>#include<cstring>#include<algorithm>#define ll unsigned long longusing namespace std;const ll mod=(ll)1<<32;ll tab[50][50]={{0},{0,1},{0,-1,1},{0,0,-1,1},{0,1,-1,-1,1},{0,0,1,-1,-1,1},{0,0,1,0,-1,-1,1},{0,0,0,1,0,-1,-1,1},{0,-1,1,1,0,0,-1,-1,1},{0,0,-1,1,1,0,0,-1,-1,1},{0,-1,0,0,2,0,0,0,-1,-1,1},{0,0,-1,0,0,2,0,0,0,-1,-1,1},{0,0,-1,-1,1,1,1,0,0,0,-1,-1,1},{0,0,0,-1,-1,1,1,1,0,0,0,-1,-1,1},{0,0,-1,0,-1,0,2,0,1,0,0,0,-1,-1,1},{0,0,0,-1,0,-1,0,2,0,1,0,0,0,-1,-1,1},{0,2,-3,0,-1,0,0,1,1,0,1,0,0,0,-1,-1,1},{0,0,2,-3,0,-1,0,0,1,1,0,1,0,0,0,-1,-1,1},{0,1,0,0,-3,0,-1,1,1,0,1,0,1,0,0,0,-1,-1,1},{0,0,1,0,0,-3,0,-1,1,1,0,1,0,1,0,0,0,-1,-1,1},{0,2,-1,0,-1,0,-3,0,0,2,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,2,-1,0,-1,0,-3,0,0,2,0,0,1,0,1,0,0,0,-1,-1,1},{0,2,1,-1,-1,-1,-1,0,-3,1,1,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,2,1,-1,-1,-1,-1,0,-3,1,1,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,1,1,2,-1,-1,-2,-1,-1,0,-2,2,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,1,1,2,-1,-1,-2,-1,-1,0,-2,2,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,1,2,0,0,1,-1,-2,-2,-1,-1,1,-1,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,1,2,0,0,1,-1,-2,-2,-1,-1,1,-1,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,3,1,0,0,-1,1,-2,-2,-2,-1,0,2,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,0,3,1,0,0,-1,1,-2,-2,-2,-1,0,2,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,2,1,2,0,0,-1,-1,0,-2,-2,-2,0,1,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,0,2,1,2,0,0,-1,-1,0,-2,-2,-2,0,1,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,-3,6,1,1,-1,2,0,-1,-1,-2,0,-2,-2,-1,1,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,-3,6,1,1,-1,2,0,-1,-1,-2,0,-2,-2,-1,1,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,-2,2,1,6,-1,0,-1,2,-1,-1,-2,-2,0,-2,-1,0,0,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,-2,2,1,6,-1,0,-1,2,-1,-1,-2,-2,0,-2,-1,0,0,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,-4,4,0,4,0,5,-2,0,-1,1,-1,-2,-2,-2,0,-1,0,-1,0,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,-4,4,0,4,0,5,-2,0,-1,1,-1,-2,-2,-2,0,-1,0,-1,0,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,-4,4,-2,5,1,2,0,4,-2,0,-2,1,-2,-2,-2,-2,1,0,-1,-1,0,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,0,-4,4,-2,5,1,2,0,4,-2,0,-2,1,-2,-2,-2,-2,1,0,-1,-1,0,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1},{0,-7,7,-3,6,-2,5,0,2,-1,4,-2,-1,-2,0,-2,-2,-2,-1,2,-1,-1,-1,0,0,1,-2,1,0,1,0,0,1,0,1,0,0,0,-1,-1,1}};ll pow(ll p,ll q){ ll ret=1; while(q) { if(q&1) { ret*=p;ret%=mod; } q>>=1; p=p*p%mod; } return ret;}int main(){ for(ll i=1;i<=40;i++) { for(ll j=0;j<=i;j++)tab[i][j]+=tab[i-1][j],tab[i][j]=(tab[i][j]%mod+mod)%mod; } ll n,m; while(~scanf("%lld%lld",&n,&m)) { ll ans=0; for(ll j=0;j<=n;j++)ans+=(tab[n][j]*pow(m,j))%mod,ans%=mod; printf("%lld\n",ans); }}
初赛五 腾讯的新游戏
勇士挑战恶魔,恶魔有n队,每队mi个
q次换防,i队前几个与j队前几个互换
1、链表实现换防
2、逐一计算攻击每队的所需防御力
3、按照防御力从小到大排序,贪心即可
初赛六
1、树形dp f[u][color]
2、再次考到容斥原理
3、dfs的复杂度是O(n)的!dfs的复杂度是O(n)!的dfs的复杂度是O(n)的!当时没想到这一点,不敢枚举最大最小值
#include<cstdio>#include<cstring>#include<vector>#define ll long long#define D(x) ((x)>-(x)?(x):-(x))using namespace std;const ll inf=1e15;ll dat[110][2],n;ll a[110],b[110],top;namespace G{ vector<ll>V[110]; ll f[110][2]; void dfs(ll u,ll fa) { ll len=V[u].size(); for(ll i=0;i<len;i++) { ll v=V[u][i]; if(v==fa)continue; dfs(v,u); } ll node; if(u==1)node=len;else node=len-1; if(node==0) { f[u][0]=dat[u][0];f[u][1]=dat[u][1];return; } if(node==1) { ll v;for(ll i=0;i<len;i++)if(V[u][i]!=fa)v=V[u][i]; f[u][0]=max(dat[u][0]+f[v][0]-(D(dat[u][0]-dat[v][0])+999)/1000*666*u, dat[u][0]+f[v][1]-(D(dat[u][0]-dat[v][1])+999)/1000*666*u); f[u][1]=max(dat[u][1]+f[v][0]-(D(dat[u][1]-dat[v][0])+999)/1000*666*u, dat[u][1]+f[v][1]-(D(dat[u][1]-dat[v][1])+999)/1000*666*u); return; } f[u][0]=f[u][1]=-inf; ll mx,mi,mxf,mif; for(ll i=0;i<len;i++)//第一个点 { ll t1=V[u][i];if(t1==fa)continue; for(ll c1=0;c1<2;c1++) { for(ll j=i+1;j<len;j++)//第二个点 { ll t2=V[u][j];if(t2==fa)continue; for(ll c2=0;c2<2;c2++) { for(ll c0=0;c0<2;c0++)//u点 { if(dat[t1][c1]>dat[t2][c2]) mx=dat[t1][c1],mxf=f[t1][c1],mi=dat[t2][c2],mif=f[t2][c2]; else mi=dat[t1][c1],mif=f[t1][c1],mx=dat[t2][c2],mxf=f[t2][c2]; mx=max(mx,dat[u][c0]); mi=min(mi,dat[u][c0]); ll ret=dat[u][c0]+mxf+mif-(mx-mi+999)/1000*666*u; ll flag=1; for(ll l=0;l<len;l++)if(l-i&&l-j)//其他点 { ll t3=V[u][l];if(t3==fa)continue; ll tmp=-inf; if(mi<=dat[t3][0]&&dat[t3][0]<=mx)tmp=max(tmp,f[t3][0]); if(mi<=dat[t3][1]&&dat[t3][1]<=mx)tmp=max(tmp,f[t3][1]); if(tmp==-inf) { flag=0;break; } else ret+=tmp; } if(flag)f[u][c0]=max(f[u][c0],ret); } } } } } } void Go() { while(~scanf("%lld",&n)) { for(ll i=1;i<=n;i++)scanf("%lld%lld",&dat[i][0],&dat[i][1]),V[i].clear(); for(ll i=1;i<n;i++) { ll x,y; scanf("%lld%lld",&x,&y); V[x].push_back(y); V[y].push_back(x); } dfs(1,-1); printf("%lld\n",max(f[1][0],f[1][1])); } }}int main(){ G::Go();}
0 0
- ZF_20160614_计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客
- 计蒜客等差数列
- 计蒜客 罗马数字
- 计蒜客 罗马数字
- 计蒜客|节假日
- 计蒜客|等边三角形
- 宏在C++中的替代解决方案
- RQNoj 合并果子 优先队列最小堆
- 第12课第3节 字符设备驱动程序之查询方式的按键驱动程序
- Base8编码:通过数字传输二进制数据
- Restful 操作
- ZF_20160614_计蒜客
- SSH Access Denied
- ARM的流水线与PC值的关系
- 第十六周项目2—阅读程序(3)
- C#托管代码调用C++非托管代码
- set集合最经典的编程题型
- 【设计模式】工厂模式
- 刘未鹏逃出肖申克系列链接
- 第十二周项目:复数类