Codeforces Round # 633 (Div. 2) D (Conclusion) E (Law + Structure)

Title link

I will not write the first three questions for water questions (water questions have been done for so long and I was awakened by myself)

 

D. Edge Weight Assignment

Topic: Give you a tree that requires you to assign values ​​for each edge

 

practice:

At first glance, this question is to find a conclusion, just push a few more trees and push it.

Conclusion: The best structure, each edge weight is different. Because the side power is infinite, there must be some legal scheme to make the side power XOR 0

If the distance between two leaf nodes is equal to 2, the answer is one less

dfs constructs the points with multiple leaf nodes minus:

5-2==3

So how to construct the minimum?

In the smallest case, there are only two cases, either 1 or 3

When the distance of all leaf nodes is even (edge ​​weight is 1), all edge weights can be equal. The answer is 1

When there is a leaf node the distance is 3 

As for how to find the distance between a leaf is an odd number, I used the root dp, there are many ways

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e5+10;
int dp[N][2],n;
vector<int>G[N];
int mi,mx,du[N],root;
void dfs1(int u,int fa)
{
    if(du[u]==1){
        dp[u][0]++;
        return ;
    }
    for(int v:G[u])
    {
        if(v==fa) continue;
        dfs1(v,u);
        dp[u][1]+=dp[v][0];
        dp[u][0]+=dp[v][1];
    }
}
void dfs2(int u,int fa)
{
    if(du[u]==1&&dp[u][1]) {
        mi=3;
        //printf("u:%d\n",u);
    }
    if(mi!=1) return ;
    for(int v:G[u])
    {
        if(v==fa) continue;
        int t0=dp[u][0];
        int t1=dp[u][1];
        dp[u][0]-=dp[v][1];
        dp[u][1]-=dp[v][0];
        dp[v][0]+=dp[u][1];
        dp[v][1]+=dp[u][0];
        dfs2(v,u);
        dp[u][0]=t0;
        dp[u][1]=t1;
    }
}
int dfs3(int u,int fa)
{
    int flag=0;
    for(int v:G[u])
    {
        if(v==fa) continue;
        flag+=dfs3(v,u);
    }
    if(flag>=2) mx-=flag-1;
    if(du[u]==1) return 1;
    return 0;
}
int main()
{
	cin>>n;
	rep(i,2,n)
	{
	    int u,v;
	    scanf("%d%d",&u,&v);
	    G[u].push_back(v);
	    G[v].push_back(u);
	    du[u]++;
	    du[v]++;
	}
	rep(i,1,n) if(du[i]>=2) root=i;

	dfs1(root,-1);
	mi=1;
	dfs2(root,-1);

	mx=n-1;
	dfs3(root,-1);
	printf("%d %d\n",mi,mx);
}

E. Perfect Triples

Topic: You need to construct a triplet from small to large and each number is unique and a ^ b ^ c = 0 is connected to the back of the sequence s in sequence, enter n to find out what the nth number is

Practice: Listen to group friends say XOR and quaternary are good brothers. Type the table according to the title:

Playing table program:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=1e5+10;
int vis[N];
void cal(int x)
{
    stack<int>sta;
    while(x)
    {
        int d=x%4;
        sta.push(d);
        x=x/4;
    }
    while(sta.size()) {
        printf("%d",sta.top());
        sta.pop();
    }
    printf(" ");
}
int main()
{
	rep(i,1,200)
	rep(j,1,200)
	rep(k,1,200){
        if(vis[i]||vis[j]||vis[k]) continue;
        if((i^j^k)==0){
             //cal(i),cal(j),cal(k);
             //puts("");
             printf("%d %d %d\n",i,j,k);
             vis[i]=1,vis[j]=1,vis[k]=1;
        }

	}
}


 

There seems to be no regularity

Change to quaternary look:

Divide each paragraph according to the 4 ^ th power line:

1 2 3

10 20 30
11 22 33
12 23 31
13 21 32

100 200 300
101 202 303
102 203 301
103 201 302
110 220 330
111 222 333
112 223 331
113 221 332
120 230 310
121 232 313
122 233 311
123 231 312
130 210 320
131 212 323
132 213 321
133 211 322



1000 2000 3000
1001 2002 3003
1002 2003 3001
1003 2001 3002
1010 2030 3020
1020 2031 3011
1021 2032 3013
1023 2033 3010
1030 2022 3012

 

I vaguely found a rule, each bit of the triplet in each segment is 0 1 2 3 changes, and the number of 0 1 2 3 consecutive with the current 4

The number of decimal places.

The second number of triples is 0 2 3 1 change.

The third number of the triple is the change of 0 3 1 2.

The rules are there, but it seems very troublesome to construct

It's also troublesome to talk about, and study the code directly:

Code reference from: code source

First find out the number p of the current n is in a row p of a certain segment of the triple and the first element of the first row of the current segment:

ll p=(n-1)/3,s=1,all=0;
while(p>=s)
{
    p-=s;
    s<<=2;
}

According to n% 3, find the number in the triple.

In summary: a very good rule and a very good construction method. .

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
    int _;cin>>_;while(_--)
    {
        ll n;
        cin>>n;
		ll p=(n-1)/3,s=1,all=0;
		//当前n处在三元组 某一段中 某一行p  当前段第一行 第一个元素 的数字s:
        while(p>=s)
        {
            p-=s;
			s<<=2;
        }
        
        //p行对应的进制变化分别是0,1,2,3     0 2 3 1      0 3 2 1
        if(n%3==1) printf("%lld\n",s+p);//第一个数直接加
        else if(n%3==2)//第二个
        {
            ll ans=s<<1,c=1;//每一段的第一行是特殊的 x 2*x 3*x
            while(p)
            {
            	//四进制的最低位
                ll x=p%4;
                if(x==1) ans+=c*2;
                else if(x==2) ans+=c*3;
                else if(x==3) ans+=c;
                p>>=2,c<<=2;
            }
            printf("%lld\n",ans);
        }
        else
        {
            ll ans=s*3,c=1;
            while(p)
            {
                ll x=p%4;
                if(x==1) ans+=c*3;
                else if(x==2) ans+=c*1;
                else if(x==3) ans+=c*2;
                p>>=2,c<<=2;
            }
            printf("%lld\n",ans);
        }

    }
    return 0;
}

 

Published 519 original articles · praised 69 · 50,000+ views

Guess you like

Origin blog.csdn.net/qq_41286356/article/details/105506582