OI 笑传 #20
我讨厌性质跟输入格式有关的东西。
20th
ARC208B
这题实现了三个版本,虽然说前两个是错的但是都是一遍写对,当练习玛丽了。
code
Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
i64 x=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
void init(){return ;}
i64 da[1000];
i64 d[1000];
bool check(int n,i64 k,int mid){
i64 res=0,lst=mid;
for(int i=2;i<=n;i++){
i64 nc=lst*2-1;
res+=nc%lst;
if(res>=k)break;
lst=nc;
}
if(res<k)return 0;
else return 1;
}
void solve(){
int n,k; cin>>n>>k;
i64 l=1,r=1e9;
while(l<r){
i64 mid=l+r>>1;
if(check(n,k,mid)){
r=mid;
}
else l=mid+1;
}
vector<i64> al;
i64 res=0,lst=r;
al.push_back(r);
for(int i=2;i<=n;i++){
i64 nc=lst*2-1;
i64 bres=res;
res+=nc%lst;
if(res>=k){
al.push_back(lst+k-bres);
break;
}
else al.push_back(nc);
lst=nc;
}
for(int i=1;i<=n-al.size();i++){
cout<<1<<' ';
}
for(int v:al){cout<<v<<' ';}
cout<<'\n';
return ;
}
int main(){
da[1]=1;
da[2]=2;
d[1]=d[2]=0;
for(int i=3;i<=40;i++){
da[i]=da[i-1]*2-1;
d[i]=da[i]%da[i-1];
d[i]=d[i-1]+d[i];
}
int T;cin>>T;
while(T--){
init();solve();
}
return 0;
}
CF1776F
轻量构造题。
code
Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
i64 x=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int ind[100];
struct ek{
int u;int v;
}e[10000];
int ans[10000];
void init(){memset(ind,0,sizeof ind);return ;}
void solve(){
int n,m;cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>e[i].u>>e[i].v;
ind[e[i].u]++;
ind[e[i].v]++;
}
if(m==(n-1)*n/2){
cout<<3<<'\n';
for(int i=1;i<=m;i++){
if(e[i].u!=1&&e[i].v!=1)ans[i]=1;
}
for(int i=1;i<=m;i++){
if(e[i].u>e[i].v)swap(e[i].u,e[i].v);
if(e[i].u==1&&e[i].v!=n)ans[i]=2;
if(e[i].u==1&&e[i].v==n)ans[i]=3;
}
for(int i=1;i<=m;i++){cout<<ans[i]<<' ';}
cout<<'\n';
return ;
}
else{
int tg=0;
for(int i=1;i<=n;i++){
if(ind[i]!=n-1){tg=i;break;}
}
for(int i=1;i<=m;i++){
if(e[i].u!=tg&&e[i].v!=tg)ans[i]=1;
else ans[i]=2;
}
cout<<2<<'\n';
for(int i=1;i<=m;i++){cout<<ans[i]<<' ';}
cout<<'\n';
}
}
int main(){
int T;cin>>T;
while(T--){
init();solve();
}
return 0;
}
CF1594D
有向边和无向边是等价的。
也打了一版错的代码,当复习 tarjan 三件套了。
code
Show me the code
ABC428C
对删除操作的处理。
code
Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
i64 x=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
struct op{
int l;int r;
}o[900000];
int cnt=0;
int main(){
int q;cin>>q;
int l=0,r=0;
string s="";
for(int i=1;i<=q;i++){
int op;cin>>op;
if(op==1){
char p;cin>>p;
s.push_back(p);
if(p==')'){
if(l==0)r++;
else l--;
}
if(p=='('){
l++;
}
cnt++;
o[cnt].l=l;o[cnt].r=r;
}
if(op==2){
s.pop_back();
cnt--;
l=o[cnt].l;r=o[cnt].r;
}
// cout<<l<<' '<<r<<'\n';
if(r==l&&r==0)cout<<"Yes"<<'\n';
else cout<<"No"<<'\n';
}
return 0;
}
ABC428D
完全平方数有类似倍数一样的前缀和性质,由此可以直接在得到值的范围后直接求出里面的完全平方数数量。
对值的范围的构造技巧。
code
Show me the code
ABC428E
树的直径的性质。
code
Show me the code
#define rd read()
#define mkp make_pair
#define ls p<<1
#define rs p<<1|1
#define rep(i,a,b) for( int i=(a); i<=(b); ++i)
#define per(i,a,b) for( int i=(a); i>=(b); --i)
#include<bits/stdc++.h>
using namespace std;
typedef long long i64;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef __int128 i128;
i64 read(){
i64 x=0,f=1;
char c=getchar();
while(c>'9'||c<'0'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
const int N=5e5+5;
const int lgr=24;
vector<int> e[N];
int d[N];
void dfs1(int u,int fa){
for(int v:e[u]){
if(v==fa)continue;
d[v]=d[u]+1;
dfs1(v,u);
}
return ;
}
int fa[N][30];
int dep[N];
void bfs(int s){
memset(dep,0x3f,sizeof dep);
queue<int> q;
q.push(s);
dep[s]=1;dep[0]=0;
fa[0][0]=0;fa[s][0]=0;
while(q.size()){
int u=q.front();
q.pop();
for(int v:e[u]){
if(dep[v]>dep[u]+1){
dep[v]=dep[u]+1;
fa[v][0]=u;
q.push(v);
for(int j=1;j<=lgr;j++){
fa[v][j]=fa[fa[v][j-1]][j-1];
}
}
}
}
return ;
}
int lca(int a,int b){
if(a==b)return a;
if(dep[a]<dep[b])swap(a,b);
for(int i=lgr;i>=0;i--)if(dep[fa[a][i]]>=dep[b])a=fa[a][i];
if(a==b) return a;
for(int i=lgr;i>=0;i--)if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
return fa[a][0];
}
int main(){
int n;cin>>n;
for(int i=1;i<n;i++){
int u,v;cin>>u>>v;
e[u].push_back(v);
e[v].push_back(u);
}
dfs1(1,0);
int l1=0,l2=0;
int md=0,ma=0;
for(int i=1;i<=n;i++){
if(md<d[i]){md=d[i];ma=i;}
if(md==d[i]){ma=max(ma,i);}
}
memset(d,0,sizeof d);
dfs1(ma,0);
l1=ma;ma=0;md=0;
for(int i=1;i<=n;i++){
if(md<d[i]){md=d[i];ma=i;}
if(md==d[i]){ma=max(ma,i);}
}
l2=ma;
bfs(1);
for(int i=1;i<=n;i++){
int lca1=lca(i,l1);
int lca2=lca(i,l2);
int d1=dep[i]+dep[l1]-2*dep[lca1];
int d2=dep[i]+dep[l2]-2*dep[lca2];
if(d1>d2)cout<<l1<<'\n';
else if(d1<d2)cout<<l2<<'\n';
else cout<<max(l1,l2)<<'\n';
}
return 0;
}
ABC428F
神人线段树题。
场上想到了分成块处理 \(1 2\) 操作也知道这种东西可以用势能分析出来是均摊就行的。但是就是不会操作 \(3\)。
赛后才知道由于初始 \(W_1<W_2<\cdots W_n\) 这种东西,包含位置是有单调性的。
。。。只能说还是注意力不够。
code
Show me the code