Submission #233156

# Submission time Handle Problem Language Result Execution time Memory
233156 2020-05-19T17:05:45 Z errorgorn Lampice (COCI19_lampice) C++14
0 / 110
5000 ms 13692 KB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
#define ll long long
#define ii pair<ll,ll>
#define iii pair<ii,ll>
#define fi first
#define se second
#define endl '\n'
#define debug(x) cout << #x << " is " << x << endl;

#define rep(x,start,end) for(auto x=(start)-((start)>(end));x!=(end)-((start)>(end));((start)<(end)?x++:x--))
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()

ll MAX(ll a){return a;}
ll MIN(ll a){return a;}
template<typename... Args>
ll MAX(ll a,Args... args){return max(a,MAX(args...));}
template<typename... Args>
ll MIN(ll a,Args... args){return min(a,MIN(args...));}

#define indexed_set tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>

struct RNG{
    typedef unsigned long long ull;
    ///taken from http://prng.di.unimi.it/xoshiro256plusplus.c
    ull s[4];

    RNG(ull a, ull b, ull c, ull d){
        ///please seed this with something legit
        s[0]=a,s[1]=b,s[2]=c,s[3]=d;

        for (int x=0;x<1024;x++) next(); //give some random
    }

    static inline ull rotl(const ull x, int k){
        return (x << k) | (x >> (64 - k));
    }


    ull next() {
        const ull result = rotl(s[0] + s[3], 23) + s[0];

        const ull t = s[1] << 17;

        s[2] ^= s[0];
        s[3] ^= s[1];
        s[1] ^= s[2];
        s[0] ^= s[3];

        s[2] ^= t;

        s[3] = rotl(s[3], 45);

        return result;
    }
}rng=RNG(423358081,274988025,50131061,866741066);

const int MOD=1000000007;
const ll P=583726327;

long long qexp(long long b,long long p,int m){
    long long res=1;
    while (p){
        if (p&1) res=(res*b)%m;
        b=(b*b)%m;
        p>>=1;
    }
    return res;
}

ll fix(ll i){
	while (i<0) i+=MOD;
	while (MOD<=i) i-=MOD;
	
	return i;
}

ll h[30];
ll powP[50005];
ll invP[50005];

int n;
string s;
vector<int> al[50005];
bool used[50005];
int parent[50005];
int subtree[50005];

void dfs(int i,int j){
    subtree[i]=1;
    for (auto it=al[i].begin();it!=al[i].end();it++){
        if (!used[*it] && *it!=j){
            dfs(*it,i);
            subtree[i]+=subtree[*it];
        }
    }
}
void centroid_decomp(int i,int p,int s){
    s>>=1;
    dfs(i,-1);
    int prev=-1;
    reloop:
    for (auto it=al[i].begin();it!=al[i].end();it++){
        if (!used[*it] && *it!=prev && subtree[*it]>s){
            prev=i;
            i=*it;
            goto reloop;
        }
    }
    ///i is now the centroid
    used[i]=true;
    parent[i]=p;
    int prev_size=s-1;
    for (auto it=al[i].begin();it!=al[i].end();it++){
        if (!used[*it]){
            if (*it!=prev){
                centroid_decomp(*it,i,subtree[*it]);
                s-=subtree[*it];
            }
        }
    }
    if (prev!=-1) centroid_decomp(prev,i,prev_size);
}

int BANNED; //this node cannot cross during dfs
int LENGTH; //length of palindrome we need to find
int ROOT;


int depth[50005];
map<ii,int> exists;
int val[500005];
int rval[500005];

vector<int> stk;

void dfs_mark(int i,int p,int id){ //this is to mark vertices during dfs
	if (i==BANNED) return;
	
	//cout<<i<<" "<<val[i]<<" "<<rval[i]<<endl;
	ii temp=ii((fix(val[i]-h[s[ROOT]-'a'])*invP[1])%MOD,depth[i]);
	
	//cout<<"adding: "<<temp.fi<<" "<<temp.se<<" "<<id<<endl;
	
	if (exists.count(temp)) exists[temp]=-1;
	else exists[temp]=id;
	
	for (auto &it:al[i]){
		if (it==p) continue;
		//val and rval get calculated first
		depth[it]=depth[i]+1;
		val[it]=(val[i]+powP[depth[it]]*h[s[it]-'a'])%MOD;
		rval[it]=(rval[i]*P+h[s[it]-'a'])%MOD;
		
		dfs_mark(it,i,id);	
	}
	
}

bool dfs_test(int i,int p,int id){ //test if palindrome exists
	if (i==BANNED) return false;
	stk.push_back(i);
	
	if (LENGTH/2<=depth[i] && depth[i]<LENGTH){
		int extra=LENGTH-depth[i]-1;
		int palin=LENGTH-extra*2;
		
		//cout<<i<<" "<<extra<<" "<<palin<<endl;
		//cout<<stk[palin-1]<<endl;
		
		if (val[stk[palin-1]]==rval[stk[palin-1]]){
			ii temp=ii((fix(val[i]-val[stk[palin-1]])*invP[palin])%MOD,extra);
			//cout<<temp.fi<<" "<<temp.se<<" "<<id<<endl;
			if (exists.count(temp) && exists[temp]!=id) return true;
		}
	}
	
	for (auto &it:al[i]){
		if (it==p) continue;
		
		if (dfs_test(it,i,id)) return true;
	}
	
	stk.pop_back();
	return false;	
}

bool can(int i){
	if (i<2) return true;
	
	LENGTH=i;
	
	rep(x,1,n+1){
		exists.clear();
		exists[ii(0,0)]=-1;
		//cout<<"trying: "<<x<<endl;
		
		depth[x]=0;
		val[x]=rval[x]=h[s[x]-'a'];
		
		ROOT=x;
		BANNED=parent[x];
		
		for (auto &it:al[x]){
			depth[it]=depth[x]+1;
			val[it]=(val[x]+powP[depth[it]]*h[s[it]-'a'])%MOD;
			rval[it]=(rval[x]*P+h[s[it]-'a'])%MOD;
			
			dfs_mark(it,x,it);
		}
		
		for (auto &it:al[x]){
			stk.clear();
			stk.push_back(x);
			if (dfs_test(it,x,it)) return true;
		}
	}
	
	return false;
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	
	rep(x,0,30) h[x]=rng.next()%MOD;
	rep(x,0,50005){
		powP[x]=qexp(P,x,MOD);
		invP[x]=qexp(powP[x],MOD-2,MOD);
	}
	
	cin>>n;
	cin>>s;
	s="$"+s;
	
	int a,b;
	rep(x,1,n){
		cin>>a>>b;
		al[a].push_back(b);
		al[b].push_back(a);
	}
	
	centroid_decomp(1,-1,n);
	
	int ans=0;
	
	int lo,hi,mi;
	
	lo=0,hi=25005;
	while (hi-lo>1){
		mi=hi+lo>>1;
		
		if (can(mi*2+1)) lo=mi;
		else hi=mi;
	}
	
	ans=max(ans,lo*2+1);
	
	lo=0,hi=25005;
	while (hi-lo>1){
		mi=hi+lo>>1;
		
		if (can(mi*2)) lo=mi;
		else hi=mi;
	}
	
	ans=max(ans,lo*2);
	
	cout<<ans<<endl;
}

Compilation message

lampice.cpp: In function 'int main()':
lampice.cpp:258:8: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   mi=hi+lo>>1;
      ~~^~~
lampice.cpp:268:8: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   mi=hi+lo>>1;
      ~~^~~
# Verdict Execution time Memory Grader output
1 Incorrect 83 ms 2304 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 5064 ms 13692 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 5043 ms 10872 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 83 ms 2304 KB Output isn't correct
2 Halted 0 ms 0 KB -