构造杂题(ing)
构造一个图,使得第层下方的点的路径数为,然后构造一条主链,通过二进制拆分,将对应位置与主链项链即可
void solve(){
add(1,++idx);
add(1,++idx);
for(int i=1;i<l;i++){
idx++;
add(idx-1,idx);
add(idx-2,idx);
idx++;
add(idx-2,idx);
add(idx-3,idx);
}
add(++idx,1);
for(int i=1;i<l;i++){
idx++;
add(idx-1,idx);
}
add(idx,2);
for(int i=1;i<=l;i++){
if(a[i]){//二进制倒数第i位
if(2*(l+1)+i+1>idx) add((i+1)*2,2);
else add((i+1)*2,2*(l+1)+i+1);
}
}
}
「CF1305D」Kuroni and the Celebration
询问叶子节点的lca,如若是ta们两个之一,那么ta(lca)为根
若不是,将 和这两条链上的点(处理)从set弹出(ta们不可能为根)
然后将加入下一轮的set中
重复此操作,直到set里只剩1个元素,ta即为根
void dfs(int u,int fa,int x){
now.erase(u);
if(u==x) return;
for(int v:G[u]) {
if(v!=fa) dfs(v,u,x);
}
}
int main(){
scanf("%d",&n);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
d[u]++;d[v]++;
}
for(int i=1;i<=n;i++) {
if(d[i]==1) now.insert(i);
}
while(now.size()>1){
nxt.clear();
while(1){
if(now.size()==1) {
nxt.insert(*now.begin());
break;
}else if(now.empty()) break;
int x=*now.begin();
now.erase(now.begin());
int y=*now.begin();
now.erase(now.begin());
int lca;
printf("? %d %d\n",x,y);
fflush(stdout);
scanf("%d",&lca);
dfs(x,0,lca);
dfs(y,0,lca);
nxt.insert(lca);
}
now=nxt;
}
printf("! %d\n",*now.begin());
fflush(stdout);
return 0;
}
我们将字符串按照相邻字符是否相同划分为多个段
对于只有A/B的段就用单独的a/b就🆗了
主要是对于AB相间的段怎么处理:
首先,对于奇数段:,共用
对于A开头的段:
-
若只用,那么用的是
-
若不是,则,,共用
对于B开头的段:
-
若只用,那么用的是
-
若不是,则,,共用
那么我们可以将这些段按照花费从小到大排序
然后若数量不够,则将sum加上,表示,共用个
w=len/2,即花费
最后将c+d与sum比较,看c+d够不够即可
int main(){
cin>>t;
while(t--){
scanf("%d%d%d%d",&a,&b,&ab,&ba);
scanf("%s",s+1);
len=strlen(s+1);
cnta=0,cntb=0;
for(int i=1;i<=len;i++){
if(s[i]=='A') cnta++;
else cntb++;
}
if(cnta!=a+ab+ba||cntb!=b+ab+ba){
printf("NO\n");
continue;
}
sum=0;
for(int i=1,j;i<=len;i=j+1){
j=i;
while(j<len&&s[j]!=s[j+1]) j++;
if((j-i+1)%2==1) sum+=(j-i+1)/2;
else{
int w=(j-i+1)/2;
if(s[i]=='A') x.push_back(w);
else y.push_back(w);
}
}
sort(x.begin(),x.end());
sort(y.begin(),y.end());
for(int i:x){
if(ab>=i) ab-=i;
else sum+=i-1;//i-1个ba
}
for(int i:y){
if(ba>=i) ba-=i;
else sum+=i-1;//i-1个ab
}
if(sum<ab+ba) printf("NO\n");
else printf("YES\n");
}
return 0;
}
这个题就是我们先sort出我们的最终数组
然后将ta们的原id反排序回去(冒泡)
也就是倒着排回去,然后每次交换的时候记录下是交换的哪两个即可
这样就保证了每个逆序对只交换了一次
int main(){
cin>>n;
for (int i=1; i<=n; i++){
cin>>a[i].first;
a[i].second=i;
}
sort(a+1,a+1+n);
for (int i=1; i<=n; i++){
b[i]=a[i].second;
}
for (int i=1; i<=n; i++) {
for (int j=1; j<n; j++) {
if (b[j]>b[j+1]) {
ans.push_back({b[j+1],b[j]});
swap(b[j],b[j+1]);
}
}
}//冒泡排序
cout<<ans.size()<<"\n";
for(int i=0;i<(int)ans.size();i++){
cout<<ans[i].first<<" "<<ans[i].second<<"\n";
}
return 0;
}
「CF1305E」 Kuroni and the Score Distribution
我们可以显然发现这样的数列满足条件的三元组的个数增长是最快的,所以我们不妨从此入手
第个数的贡献为
我们可以一直列下去,直到(满足条件的三元组的个数)>=m
此时我们应该考虑如何在现有基础上将k缩小为m
我们可以比较不是很显然地发现,n(最后一项的数值)每增加2,k就减少1,
因此我们可以通过增大后面的数的数值来缩小k
使k=m即可
由于有n的限制,我们将后面的数随便填一些大的数(ta们的间隔也要大),
那么这个题就做完了
int main(){
scanf("%lld%lld",&n,&m);
for (ll i=1;i<=n;i++){
a[i]=i;
czc+=(i-1)/2;
if(czc>=m){
a[i]+=2*(czc-m);
ll add=1e9;
for (ll j=n;j>i;j--){
a[j]=(add-=(a[i]+1));
}
fg=1;
break;
}
}
if(!fg) {
printf("-1\n");
}else{
for(ll i=1;i<=n;i++){
printf("%lld ",a[i]);
}
}
return 0;
}
「CF487C」 Prefix Product Sequence
由于我们的(就是n-1位置的前缀积)包含了的所有因数(除了),
所以必然为0,
但是如果为质数肯定就不会出现这种情况(因为前面没有ta的因数(1不算))
所以如果是合数的话,肯定就GG
这里有特殊情况:4
因为
4也是可以的,所以需要特判一下
我们的1必须放在第一个,因为如果放1在中间的话,那当前位置与前一个的前缀积就是一样的,mod n的值自然一样,就GG了
我们的n必须放在最后一个,因为如果放n在中间的话,那当前位置及以后的前缀积mod n的值都为0,就GG了
考虑剩下的n-2个数
这样的序列是完全没有问题的
因为第项的前缀积为
然后我们通过逆元可以将分数转换为整数就🆗了
int main(){
pre();//质数
scanf("%lld",&n);
if(n==4||!p[n]){
printf("YES\n");
if(n==4){
printf("1\n3\n2\n4\n");//特判
return 0;
}
}else{
printf("NO\n");
return 0;
}
a[1]=1,a[n]=n;
for(ll i=2;i<n;i++){
a[i]=power(i-1,n-2)%n*i%n;
}
for(ll i=1;i<=n;i++){
printf("%lld\n",a[i]);
}
return 0;
}
就是先走轻链,放在当前点的上一层
走重链的话,就放在这一层。。。。
没了
void dfs(ll x,ll fa){
sz[x]=1;
son[x]=-1;
for(ll i=hd[x];i;i=nxt[i]){
ll y=to[i];
if(y==fa) continue;
f[y]=x;
dfs(y,x);
sz[x]+=sz[y];
if(son[x]==-1||sz[son[x]]<sz[y]) son[x]=y;
}
}
void dfs1(ll x,ll yy){
//cout<<"---"<<x<<" "<<yy<<"\n";
X[x]=++c[yy],Y[x]=yy;
if(son[x]==-1){
return ;
}
for(ll i=hd[x];i;i=nxt[i]){
ll y=to[i];
if(y==f[x]||y==son[x]) continue;
dfs1(y,yy+1);
}
dfs1(son[x],yy);
}
本文作者:_Youngxy
本文链接:https://www.cnblogs.com/yvette1217/p/16627760.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步