[20190725NOIP simulation tests 8] problem solution

Barley

T1

Flood title, the title to see what the first few letters added to the end of the same group of inexplicable panic on exam

Later we found no direct brain will be able to hash $ O (n) $

KMP also be cut

Carefully read the title, distinguished array of small

#include<cstdio>
#include<iostream>
#include<cstring>
#define re register
using namespace std;
typedef unsigned long long ull;
const int N=200005,base=131;
int T,la,lb;
ull power[N],ha[N],hb[N];
char A[N],B[N],ed[3];
inline void ini()
{
    for(int i=0;i<=la;i++)
        ha[i]=hb[i]=0;
}
inline void work()
{
    scanf("%d%d",&la,&lb);
    scanf("%s",A+1);
    scanf("%s",ed);
    ini();
    for(re int i=1;i<=lb;i++)
        B[i]=A[i];
    B[++lb]=ed[0];
    for(re int i=1;i<=lb;i++)
        hb[i]=hb[i-1]*base+B[i];
    for(re int i=1;i<=la;i++)
        ha[i]=ha[i-1]*base+A[i];
    //debug();while(1);
    int ans=0;
    for(re int i=1;i<=min(la,lb);i++)
    {
        if(i==1)
        {
            if(A[1]==B[lb])ans=1;
            continue;
        }
        if(ha[i]==hb[lb]-hb[lb-i]*power[i])
            ans=max(ans,i);
        //cout<<geta(1,i)<<' '<<getb(lb-i+1,lb)<<endl;
    }
    printf("%d\n",ans);

}
int main()
{
    scanf("%d",&T);
    power[0]=1;
    for(re int i=1;i<=N;i++)
        power[i]=power[i-1]*base;
    while(T--)work();
    return 0;
}
View Code

 

T2

FIG paint can be found in so-called "only way" is omitted so that the link 1 and n are not the point

These points must then cut the original point, and satisfies n deleted after a longer Unicom

So the idea probably came out: run $ Tarjan $, then fucks satisfy the second condition

Difficult to find, to meet the latter, the search tree if and only if n is the sub-tree of the determined cut points

Then this condition to reflect on what is it $ Tarjan $ algorithm?

I.e. for the cut point x, y connected to it a point, to meet $ dfn [y] \ leq dfn [n] $

why?

Consider $ dfn [] $ actually means: a time stamp for each access point is, we can use it to determine the point has to be accessed

If y and n are in different sub-tree (not true situation):

First visit and then visit n y: Obviously $ dfn [y]> dfn [x] $, is not satisfied

Conversely: $ dfn [y] $ updated and $ dfn [n] $ not updated, not satisfied

If y n with the same tree:

Before y n / y is the n: Founded

n Before y (not true): Obviously at this time $ dfn [y]> dfn [n] $, is not satisfied

 

Proposition is proved.

inline void tarjan(int x)
{
    low[x]=dfn[x]=++ind;
    int flag=0;
    for(int i=head[x];i;i=nxt[i])
    {
        if(!dfn[to[i]])
        {
            tarjan(to[i]);
            low[x]=min(low[x],low[to[i]]);
            if(low[to[i]]>=dfn[x])
            {
                flag++;
                if((x!=1||flag>1)&&dfn[to[i]]<=dfn[n])iscut[x]=1;
            }
        }
        else low[x]=min(low[x],dfn[to[i]]);
    }
}

 

There is another problem: if you want a single thought in n sub-Tapping point where it is easy to write dfn [x] <dfn [n]

However, the amount is actually not enough, you get 30 points, good results (fog

why?

If n is on a route starting from the x reversion was ended.

Paint can play yourself.

T3

Metaphysical questions, point solution to a problem I see big brother

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=1000005;
const ll inf=0x7fffffffffff;
int T;
char str[N];
int s[N<<1],cnt[N<<1],len;
ll val[N<<1];
void ini()
{
    for(int i=1;i<=len*2;i++)
        s[i]=cnt[i]=val[i]=0;
}
void work()
{
    ll ans=inf;
    scanf("%s",str+1);
    len=strlen(str+1);
    ini();
    for(int i=1;i<=len;i++)
        s[i]=s[i+len]=(str[i]=='B'?0:1);
    /*for(int i=1;i<=(len<<1);i++)
        cout<<s[i];*/
    for(int i=1;i<=(len<<1);i++)
        cnt[i]=cnt[i-1]+s[i],val[i]=val[i-1]+i*s[i];
    int p=1;
    for(int i=1;i<=len;i++)
    {
        ll res=inf;
        for(int j=p;j<=i+len+1;j++)
        {
            ll lnum=cnt[j-1]-cnt[i-1];
            ll rnum=cnt[i+len-1]-cnt[j-1];
            ll sum=(val[j-1]<<1)-val[i-1]-lnum*i+rnum*1LL*(i+len-1)-val[i+len-1]-(lnum-1)*lnum/2-(rnum-1)*rnum/2;
            if(sum>res)break;
            res=sum,p=j;
            ans=min(ans,res);
        }
    }
    cout<<ans<<endl;
}
int main()
{
    //cout<<0x7fffffffffff<<endl;while(1);
    scanf("%d",&T);
    while(T--)work();
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Rorschach-XR/p/11247992.html