F是计数于是就做(kan ti jie)了= =

B - Box and Ball

模拟一下 每个盒子开一个d表示有的球数 可能存在红球的打个标记 传递一下就行了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mxn 100010
using namespace std; bool vis[mxn];
int d[mxn]; int main()
{
int x,y,n,m,ans=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) d[i]++;
vis[1]=1;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
d[x] --;
d[y] ++;
if(vis[x]) vis[y]=1;
if(!d[x]) vis[x]=0;
}
for(int i=1;i<=n;i++) if(vis[i]) ans++;
printf("%d\n",ans);
return 0;
}

C - Knot Puzzle

很明显只要有一段(或者两段)能>=l就可以 然后细节注意一下就行了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mxn 100010
using namespace std; int a[mxn],n,l; int main()
{
int pos=0;
scanf("%d%d",&n,&l);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]+a[i-1]>=l) pos=i;
}
if(!pos) printf("Impossible\n");
else
{
printf("Possible\n");
for(int i=n-1;i>=pos;i--) printf("%d\n",i);
for(int i=1;i<pos;i++) printf("%d\n",i);
}
return 0;
}

D - Stamp Rally

看题以后就有思路了 大概就是从小到大加边然后看一下联通块大小是不是>=k 然而多组询问不能直接做

就需要整体二分= = 去学了一发整体二分和可持久化并查集(然后发现用不到)就写完了 还是比较舒适的

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mxn 100010
using namespace std; struct node{int sz,fa;}t[mxn];// 记得初始化!&&按sz合并
struct cz{int fx,x;}c[mxn];// 存x连到fx
struct query{int x,y,sz;}q[mxn];
struct edge{int x,y;}e[mxn];
int n,m,ans[mxn],id[mxn]; int find(int x)
{
while(t[x].fa!=x) x=t[x].fa;
return x;
} void merge(int id,int x,int y) // merge y to x
{
x = find(x); y = find(y);
if(x==y) return;
if(t[x].sz < t[y].sz) swap(x,y);
c[id].fx = x; c[id].x = y;
t[y].fa = x; t[x].sz += t[y].sz;
} void cancel(int id)
{
int x = c[id].fx;int y = c[id].x;
if(!x || !y) return;
t[x].sz -= t[y].sz; t[y].fa = y;
} int now,c1[mxn],c2[mxn];
void work(int l,int r,int L,int R)// [l,r] query [L,R] val
{
//printf("%d %d %d %d\n**",l,r,L,R);
//for(int i=l;i<=r;i++) printf("%d ",id[i]);
//printf("\n");
if(r<l) return;
if(L==R)
{
for(int i=l;i<=r;i++)
ans[id[i]] = L;
return;
}
int MID = L+R>>1;
while(now<MID) now++,merge(now,e[now].x,e[now].y);
while(now>MID) cancel(now),now--; int l1,l2; l1=l2=0;
for(int i=l;i<=r;i++)
{
int x=q[id[i]].x,y=q[id[i]].y,k=q[id[i]].sz,fx=find(x),fy=find(y);
int ff=0;
if(fx==fy&&t[fx].sz>=k) ff=1;
if(fx!=fy&&t[fx].sz+t[fy].sz>=k) ff=1;
if(ff) c1[++l1] = id[i];
else c2[++l2] = id[i];
} int mid = l+l1-1;
for(int i=1;i<=l1;i++) id[l+i-1] = c1[i];
for(int i=1;i<=l2;i++) id[mid+i] = c2[i]; work(l,mid,L,MID); work(mid+1,r,MID+1,R);
} int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) t[i].sz=1,t[i].fa=i;
for(int i=1;i<=m;i++)
scanf("%d%d",&e[i].x,&e[i].y);
int Q;
scanf("%d",&Q);
for(int i=1;i<=Q;i++)
{
scanf("%d%d%d",&q[i].x,&q[i].y,&q[i].sz);
id[i] = i;
}
work(1,Q,1,m);
for(int i=1;i<=Q;i++)
printf("%d\n",ans[i]);
return 0;
}

E - Candy Piles

神仙博弈做不来= =

观察操作其实就是 从大到小选一些拿走 然后其余的是每堆拿一个 (然后我就蠢蠢的开始判定性问题了)

看一发题解还是很神仙的

就是把这些糖摆成阶梯型 然后第一个操作拿走一列 第二个操作拿走一行【似曾相识?有一道考试题也是这个哦 那个是需要dp计数】

继续转换将其变成Lattice Path

然后操作变成向右走或者向上走 然后谁到边界谁就输

然后可以观察到一个斜对角线上的胜负状态是相同的

证明是这个样子 设现在第一个操作使用了x次 第二个操作使用了y次

当(x+1,y+1)是合法操作的时候

1.(x+1,y+1)先手必败也就说明无论(x+1,y)和(x,y+1) 后手就都能把这个状态转移给先手 那么这个时候均为必败态

2.(x+1,y+1)先手必胜 也就说明(x+2,y+1)或者(x+1,y+2)中有先手必败态 然后根据1后手无论是从x到(x+1,y)或者(x,y+1)都是必败的 那么这个时候是先手必胜

所以得到这个性质了 我们的0,0出发点位于的对角线就是x=y那么找到最大的合法(x,x)

这个时候它只能往右走到头 或者往上走到头 判断一下这两个只要有一个是先手必胜(奇数步)那么一定就是先手必胜态

代码实现有点烦= = 0,1数清楚= =

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mxn 100010
using namespace std; int n,a[mxn];
bool cmp(int x,int y)
{
return x>y;
}
void work(int id)
{
int i,qaq=0;
for(i=id+1;a[i]==id&&i<n;i++) qaq^=1;
if((a[id]-id)%2==1||qaq) printf("First\n");
else printf("Second\n");
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]),a[i]--;
sort(a,a+n,cmp); int i;
for(i=0;i<n;i++)
if(a[i+1]<i+1)
{
work(i);break;
}
return 0;
}

F - Leftmost Ball

神仙计数 感觉自己计数水平真的好低= =

观察性质可以得到 每一个颜色的k-1个带颜色球一定是位于其中一个0之后的 那么对于所有的0后面一定是>=k-1的多个是还要加上后面的0的个数的

然后我们发现每放一个0色球 后面可以放的颜色就多一种

然后每放一个非0球 其实可以直接算出后面把这个颜色放完的方案数

就可以列出状态f[x][y]表示放了x个0色球 放完了y种非零色球

观察到 颜色重复计算比较麻烦 于是可以把n!提出来 变成[1,n]这n个颜色顺着放就简洁很多

那么0色球的转移就是 f[x][y]+=f[x-1][y]

非0色球的转移就是 f[x][y] += f[x][y-1] * C(tot-(k-1)*(y-1)-1,k-2)

就是说把这个颜色所有的都放完了很明显是不影响状态的 直接把位置删掉就可以了

最后不要忘了n!

这个题主要的思路就是 通过提取n!来解决多颜色转移之间的互相影响 利用0色可以带来非0色的贡献 来进行转移 做题过程中注意可以通过一个条件来进行转移的可以先不直接计算贡献 保留他的状态 在合适的地方选择转移

计数好好练= =

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mdn 1000000007
using namespace std; int f[2100][2100];
int inv[2100*2100],fac[2100*2100];
int n,k; int ksm(int bs,int mi)
{
int ans=1;
while(mi)
{
if(mi&1) ans=(ll)ans*bs%mdn;
bs=(ll)bs*bs%mdn; mi>>=1;
}
return ans;
} int C(int x,int y)
{
if(x<y) return 0;
return (ll)fac[x] * inv[y] %mdn * inv[x-y] %mdn;
} int main()
{
scanf("%d%d",&n,&k);
if(k==1||n==1){printf("1\n");return 0;}
inv[0]=fac[0]=1; int tot=n*k;
for(int i=1;i<=tot;i++) fac[i]=(ll)fac[i-1]*i%mdn;
inv[tot] = ksm(fac[tot],mdn-2);
for(int i=tot-1;i;i--) inv[i]=(ll)inv[i+1]*(i+1)%mdn;
f[0][0]=1;// printf("%d\n",inv[tot]);
for(int i=1;i<=n;i++)
{
for(int j=0;j<=i;j++)
{
f[i][j] += f[i-1][j];
if(j) f[i][j] += (ll)f[i][j-1] * C(tot-i-(k-1)*(j-1)-1,k-2) %mdn;
f[i][j]%=mdn;
//printf("%d %d %d\n",i,j,f[i][j]);
}
}
printf("%d\n",(ll)f[n][n]*fac[n]%mdn);
return 0;
}

AGC002[BCDEF]题解的更多相关文章

  1. AGC003[BCDEF]题解

    2018-12-28 有点累EF明天再写叭=v= 2018-12-29 update EF B - Simplified mahjong 可以注意到 一段连续的非0序列都可以凑出 就是显然%2=0的可 ...

  2. AtCoder AGC002 简要题解

    从今天开始,联赛之前大约要完成前 \(20\) 套 \(\rm AGC\),希望不要鸽. A 略 B 感觉这题比 \(\rm C\) 题难. 考虑对于每个时刻维护每个位置是否可能出现红球,那么一个时刻 ...

  3. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  4. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  5. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  6. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  7. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  8. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  9. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

随机推荐

  1. asp.net选择文件夹上传

    HTML部分 <%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="index.aspx. ...

  2. Codeforces Round #608 (Div. 2) E - Common Number (二分 思维 树结构)

  3. [CSP-S模拟测试]:Park(树上DP)

    题目描述 公园里有$n$个雕像,有$n-1$条道路分别连接其中两个雕像,任意两个雕像可以直接或间接相连.现在每个景点$i$聚集着$P_i$只鸽子,旅行家手里有$v$数量的面包屑. 一旦旅行家在雕像$i ...

  4. 浅析java中的string

    在学习java36讲的时候看到评论区有人提出的一个问题: String s1 = new String("do"); s1.intern(); String s2 = " ...

  5. flask之二

    flask之二 预热 在渲染模板的时候,默认会从项目根路径下的templates目录下查找模板 如果想要指定模板路径的时候,就在初始化APP的时候,这样操作即可: app = Flask(__name ...

  6. oracle、sql developer 删除某用户下所有的表

    1.在sql developer内   select 'drop table "'||table_name||'";'   from cat   where table_type= ...

  7. Python中import的使用方法

    源文出处: "import"的本质参照: Python中import机制 python导入自定义模块和包

  8. 【The type javax.servlet.http.HttpServletRequest cannot be resolved】解决方案

    是缺少serverlet的引用库,解决如下 1.工程右键-properties->java build path 2.在java build path的libraries tab页中选择Add ...

  9. Iterator 和 ListIterator 对比

    Iterator 的方法 //是否还有下一个 boolean hasNext(); //返回下一个 E next(); //移除返回的下一个 void remove(); ListIterator 的 ...

  10. Vue.js的列表数据的同步更新方法

    这次给大家带来Vue.js的列表数据的同步更新方法,Vue.js列表数据同步更新方法的注意事项有哪些,下面就是实战案例,一起来看一下. 数组的 push(),pop(),shift(),unshift ...