比赛链接:https://codeforces.com/contest/1749
题解:
AB
水题
// by SkyRainWind
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define pii pair<int,int>
using namespace std;
typedef long long LL;
const int inf = 1e9, INF = 0x3f3f3f3f;
int r[15],c[15];
void solve(){
int n,m;scanf("%d%d",&n,&m);
memset(r,0,sizeof r);memset(c,0,sizeof c);
for(int i=1;i<=m;i++){
int x,y;scanf("%d%d",&x,&y);
r[x] = c[y] = 1;
}
int fg = 0;
for(int i=1;i<=n;i++)
fg |= r[i] == 0,
fg |= c[i] == 0;
if(fg)puts("YES");
else puts("NO");
}
signed main(){
int te;scanf("%d",&te);
while(te--)solve();
return 0;
}
// by SkyRainWind
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define pii pair<int,int>
using namespace std;
typedef long long LL;
const int inf = 1e9, INF = 0x3f3f3f3f;
signed main(){
int te;scanf("%d",&te);
while(te--){
int n;scanf("%d",&n);
LL sum=0,mx=-1e18;;
for(int i=1,x;i<=n;i++)scanf("%d",&x),sum+=x;
for(int i=1,x;i<=n;i++)scanf("%d",&x),sum+=x,mx=max(mx,1ll*x);
printf("%I64d\n",sum-mx);
}
return 0;
}
C
Bob肯定优先取小的,Alice优先取大的。枚举k暴力模拟这个过程即可
// by SkyRainWind
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define pii pair<int,int>
using namespace std;
typedef long long LL;
const int inf = 1e9, INF = 0x3f3f3f3f;
void solve(){
int n;scanf("%d",&n);
int a[105];
int bin[105],ain[105];memset(bin,0,sizeof bin);memset(ain,0,sizeof ain);
for(int i=1;i<=n;i++)scanf("%d",&a[i]),++bin[a[i]],++ain[a[i]];
for(int i=2;i<=100;i++)ain[i]+=ain[i-1];
int bbin[105],aain[105];
memcpy(bbin,bin,sizeof bbin);memcpy(aain,ain,sizeof aain);
int qz = 0;
for(int k=100;k>=1;k--){
memcpy(bin,bbin,sizeof bin);memcpy(ain,aain,sizeof ain);
int gg=0;qz=0;
for(int i=k;i>=1;i--){
if(ain[i] - qz <= 0){
gg=1;break;
}
if(bin[i] == 0)
for(int j=i;j>=1;j--)
if(bin[j]){--bin[j];--ain[j];break;}
else -- ain[j];
++ qz;
}
if(!gg){printf("%d\n",k);return ;}
}
puts("0");
}
signed main(){
int te;scanf("%d",&te);
while(te --)solve();
return 0;
}
D
[1..1]显然是一组解,考虑能不能有其它解
考虑容斥,什么情况下无解?对于所有的a[i],所有的\(1\leq j \leq i\),都有\(gcd(a[i],j) \neq 1\)
显然只需要考虑素因子即可,也即是1~i的所有素数即可
从1~n,如果当前i为素数,那么\(cds = cds \times i\),当前这一位出现不合法序列的次数是i/cds,然后 tmp = tmp * i/cds,tmp表示的就是长度为 i 的所有不合法序列的个数,对于所有的i计算一下即可
总共的情况是什么呢?因为每一位可以任意取,就是m+m*m+...+pw(m,n)
容斥一下即可
需要快速乘
// by SkyRainWind
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define pii pair<int,int>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int inf = 1e9, INF = 0x3f3f3f3f, maxn = 3e5 + 5, mod=998244353;
int notpm[maxn], pm[maxn], pcnt=0;
void xxs(){
notpm[1] = 1;
for(int i=2;i<=300000;i++){
if(!notpm[i]){
pm[++ pcnt] = i;
}
for(int j=1;j<=pcnt && i * pm[j] <= 300000; j++){
notpm[i*pm[j]] = 1;
if(i%pm[j] == 0)break;
}
}
}
int n;
LL m;
LL bs = 1, nbs = 1;
int gg = 0;
int tmp =1 ;
inline LL ksc(LL x,LL y,LL p){
LL z=(long double)x/p*y;
LL res=(ULL)x*y-(ULL)z*p;
return (res+p)%p;
}
signed main(){
scanf("%d%I64d",&n,&m);
xxs();
int pi = 1;
LL ans = 0;
for(int i=1;i<=n;i++){
bs = ksc(bs, m, mod);
// bs = 1ll * bs * m % mod;
if(pm[pi] == i && !gg){
nbs = 1ll * nbs * pm[pi];
if(nbs > m){
gg = 1;
}
++ pi;
}
(ans += bs) %= mod;
if(!gg){
tmp = ksc(tmp, m/nbs, mod);
// tmp = 1ll * tmp * (m/nbs) % mod;
(ans += mod - tmp) %= mod;
}
// cout << nbs << " "<< bs << " " << gg << '\n';
}
printf("%I64d\n",ans);
return 0;
}
E
我的01bfs博客中有这个题
F
考虑简化版:对每个点子树中距离这个点为d(0~20)的所有点进行修改,查找点权?
显然直接对这个点修改,查询的时候对于所有的0~20的树,求ans0[fa[x]] + ans1[fa[fa[x]]] + ... 即可
回到这个题,(u,v)路径,设lca为lc
可以拆成这3个路径:[u,lc) (lc,v] lc及fa[lc],...
[u,lc):按照简化版的处理,对于ansd[u]+k, ansd[fa[u]]+k, ... ansd[son[lc]]+k,表示对于u的子树中距离u为d的点权都+k,...
注意这里会存在son[lc]子树中距离son[lc]距离<d的点没有处理,但是这块能被包含在lc fa[lc] ... 中,此处不在赘述
[v,lc):同理
lc fa[lc] .. : 手玩一下发现ansd[lc]+k ans(d-1)[lc]+k ans(d-1)[fa[lc]]+k ans(d-2)[fa[lc]]+k ... 可以涵盖所有情况。注意如果到根了,需要把d d-1 d-2.. 0都给加上
因此我们需要实现的是:树上链加、单点加、单点查询
树剖解决,也可以树状数组
时间复杂度O(qdlogn)
// by SkyRainWind
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mpr make_pair
#define debug() cerr<<"Yoshino\n"
#define rep(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
#define pii pair<int,int>
using namespace std;
typedef long long LL;
const int inf = 1e9, INF = 0x3f3f3f3f, maxn = 2e5+5;
int n;
vector<int>g[maxn];
int a[maxn];
int dfn[maxn], seq[maxn], dfs_clock;
int dep[maxn], heavy[maxn], top[maxn], sz[maxn], fa[maxn];
struct seg{
int sum,lazy;
}se[maxn << 2][23];
void dfs1(int x,int fat){
fa[x] = fat;
sz[x] = 1;
dep[x] = dep[fat] + 1;
for(int u : g[x]){
if(u == fat)continue;
dfs1(u, x);
sz[x] += sz[u];
if(!heavy[x] || sz[u] > sz[heavy[x]])
heavy[x] = u;
}
}
void dfs2(int x,int now){
top[x] = now;
dfn[x] = ++ dfs_clock;
seq[dfs_clock] = x;
if(!heavy[x])return ;
dfs2(heavy[x], now);
for(int u : g[x]){
if(u == heavy[x] || u == fa[x])continue;
dfs2(u,u);
}
}
void build(int x,int y,int num){
for(int i=0;i<=20;i++)se[num][i].sum = se[num][i].lazy = 0;
if(x == y){
return ;
}
int mid = x + y >> 1;
build(x,mid,num << 1);build(mid+1, y, num<<1 | 1);
}
void pushdown(int l,int r,int num,int d){
if(!se[num][d].lazy)return ;
int mid = l+r>>1;
(se[num << 1][d].sum += 1ll*(mid-l+1)*se[num][d].lazy);
(se[num << 1|1][d].sum += 1ll * (r-mid)*se[num][d].lazy);
se[num << 1][d].lazy += se[num][d].lazy;
se[num << 1|1][d].lazy += se[num][d].lazy;
se[num][d].lazy = 0;
}
int getlca(int x,int y){
int tx = top[x], ty = top[y];
while(tx != ty){
if(dep[tx] < dep[ty])swap(x, y), swap(tx, ty);
x = fa[tx], tx = top[x];
}
if(dep[x] > dep[y])return y;
return x;
}
void update(int x,int y,int k,int l,int r,int num,int d){
if(x <= l && r <= y){
(se[num][d].sum += 1ll * (r-l+1) * k);
se[num][d].lazy += k;
return ;
}
pushdown(l,r,num,d);
int mid = l+r >> 1;
if(y <= mid)update(x,y,k,l,mid,num<<1,d);
else if(x > mid)update(x,y,k,mid+1,r,num<<1|1,d);
else update(x,y,k,l,mid,num<<1,d), update(x,y,k,mid+1,r,num<<1|1,d);
se[num][d].sum = (se[num<<1][d].sum + se[num<<1|1][d].sum);
}
void upd(int to,int k,int l,int r,int num,int d){
if(l == r){
se[num][d].sum += k;
return ;
}
pushdown(l,r,num,d);
int mid = l+r>>1;
if(to<=mid)upd(to,k,l,mid,num<<1,d);
else upd(to,k,mid+1,r,num<<1|1,d);
se[num][d].sum = se[num << 1][d].sum + se[num<<1|1][d].sum;
}
void access(int x,int k,int d){
int curd = d;
while(1){
upd(dfn[x],k,1,n,1,curd);
if(curd == 0)break;
upd(dfn[x],k,1,n,1,--curd);
if(x == 1)break;
x = fa[x];
}
while(curd >= 1)upd(dfn[1],k,1,n,1,--curd);
}
int query(int to,int l,int r,int num,int d){
if(l == r)return se[num][d].sum;
int mid = l+r>>1;
pushdown(l,r,num,d);
if(to <= mid)return query(to,l,mid,num<<1,d);
else return query(to,mid+1,r,num<<1|1,d);
}
void chain_add(int x,int y,int k,int d){
// printf("(%d,%d)\n",x,y);
int tx = top[x], ty = top[y];
while(tx != ty){
if(dep[tx] < dep[ty])swap(x, y), swap(tx, ty);
update(dfn[tx], dfn[x], k, 1, n ,1, d);
x = fa[tx], tx = top[x];
}
if(dep[x] > dep[y])swap(x, y);
update(dfn[x], dfn[y], k, 1, n, 1, d);
}
signed main(){
scanf("%d",&n);
for(int i=1;i<=n-1;i++){
int x,y;scanf("%d%d",&x,&y);
g[x].push_back(y), g[y].push_back(x);
}
dfs1(1,0);
dfs2(1,1);
build(1,n,1);
int m;scanf("%d",&m);
while(m --){
int op;scanf("%d",&op);
if(op == 1){
int x;scanf("%d",&x);
int curx = x;
int ans = 0;
for(int d = 0;d<=20;d++){
ans += query(dfn[curx],1,n,1,d);
if(curx == 1)break;
curx = fa[curx];
}
printf("%d\n",ans);
}
if(op == 2){
int u,v,k,d;scanf("%d%d%d%d",&u,&v,&k,&d);
int lc = getlca(u, v);
// printf("?? %d\n",lc);
if(lc == u || lc == v){
int tx = lc == u ? v : u;
int ty = lc;
chain_add(tx,ty,k,d);
upd(dfn[lc],-k,1,n,1,d);
access(lc, k, d);
}else{
chain_add(u,lc,k,d);
upd(dfn[lc],-k,1,n,1,d);
chain_add(v,lc,k,d);
upd(dfn[lc],-k,1,n,1,d);
access(lc, k, d);
}
}
}
return 0;
}
标签:lc,int,题解,CF,long,maxn,1749,include,define
From: https://www.cnblogs.com/SkyRainWind/p/16856709.html