Educational Codeforces Round 81

E

Subject to the effect

Given a permutation P P, and an array A A represents an energy value for each position of the arrangement, requiring the arrangement from an intermediate position into a right and left two, and some number of moving left to right, the right number of some move to the left, so that all values for all values less than the right to the left . An energy value for the cost of moving the location. The minimum energy value required to meet the required conditions. Note that if there is no number one side, we also believe that it meets the above conditions (false premise proposition is true then the entire thing).

Solution:
First, know the final answer is definitely the first two sets is the empty set either [1 ~ k], the second is [k + 1 ~ n];

So we have to enumerate k, but also to enumerate the cut point should be cut from where, when we found that for K, we can work out with the prefix and represents a different set of costs spent for the K's (as we will eventually left 1 2 3 4 ... is this);

For example, we k = 1, it represents the final form of a set of left, right is 2 ~ n, k = 3, represents the final form of the left 123 and right for the two sets of 4 ~ n;

In the condition that each of k, the next point is selected such that the cut takes a minimum cost of transforming the

We cut point for traverse, assumed that the current cut point i, iqwe, uo p ..

Suppose i = 5, then [1,4] here should add weight 5 weight -a [5], indicates these becomes k = k + 1 = 5 1 ~ 4, it should be set out from the right in to the left of the increased cost of collection, so [5, n] here should be a minus offset [5] before his inclusion of the right to spend a set,

That is about the formation of two kinds of pictures you cut a 5, you choose k = 4, is left free but we had to get a 5 extra supplement 1234 spending, or the right have chosen to spend a good 5 6 7 ..n of good budget, this time to 5 prepared to spend removed.

Why not add directly from where a 4 [5], 123 have it, because you spend 12 in advance, because we will move the cut point is, you can cut back to 534 this out.

So we are the tree line maintenance intervals, each point takes the value of k (so there are l = 0, r = n, instead of l = 1, r = n, because you may not need to take something from the right k, may beginning two perfect be divided), to take on the bin min.

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,p[200005],a[200005],id[200005];
ll minv[800005],val[200005],addv[800005];
void pushup(int rt)
{
    minv[rt]=min(minv[rt<<1],minv[rt<<1|1]);
}
void pushdown(int rt)
{
    if(addv[rt])
    {
        ll t=addv[rt];
        minv[rt<<1]+=t;minv[rt<<1|1]+=t;
        addv[rt<<1]+=t;addv[rt<<1|1]+=t;
        addv[rt]=0;
    }
}
void build(int rt,int l,int r)
{
    int mid=(l+r)>>1;
    if(l==r){minv[rt]=val[l];return;}
    build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
    pushup(rt);
}
void add(int rt,int l,int r,int ql,int qr,ll v)
{
    int mid=(l+r)>>1;
    if(ql<=l&&r<=qr)
    {
        addv [rt] + = v; minv [rt] + = v;
        return;
    }
    pushdown(rt);
    if(ql<=mid)add(rt<<1,l,mid,ql,qr,v);
    if(qr>mid)add(rt<<1|1,mid+1,r,ql,qr,v);
    pushup(rt);
}
int main ()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)scanf("%d",&p[i]),id[p[i]]=i;
    for(int i=1;i<=n;++i)scanf("%d",&a[i]);
    for(int i=1;i<=n;++i)val[i]=val[i-1]+a[id[i]];
    build(1,0,n);
    ll ans=(ll)1e18;
    for(int i=1;i<n;++i)
    {
        add(1,0,n,0,p[i]-1,a[i]);
        add(1,0,n,p[i],n,-a[i]);
//        cout<<minv[1]<<endl;
        years = min (years minv [1]);
    }
    cout<<ans<<endl;
}

  D

Provided G C D ( A , m ) = X GCD (A, m) = X, there are A = K . 1 X , m = K 2 X
may know G C D ( A + B , m ) = X , there is A + B = K . 3
The question now becomes, in the closed interval [ k . 1 , k . 1 + k 2 - . 1 ] how many inner k2 coprime
split into prefix problems,n prime factor decomposition of the factor to inclusion and exclusion

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline LL read()
{
    LL x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int T;
LL a,m,x,k1,k2;
LL gcd(LL a,LL b){return b==0 ? a : gcd(b,a%b);}
#include<vector> 
vector<LL> pme;
LL count_prime(LL x,LL n){
    pme.clear();
    LL i,j;
    for(i=2;i*i<=n;i++)
        if(n%i==0){
            pme.push_back(i);
            while(n%i==0)n/=i;
        }
    if(n>1)pme.push_back(n);
    LL sum=0,value,cnt;
    for(i=1;i<(1<<pme.size());i++){
        value=1;
        cnt=0;
        for(j=0;j<pme.size();j++){
            if(i&(1<<j)){
                value*=pme[j];
                cnt++;
            }
        }
        if(cnt&1)
            sum+=x/value;
        else sum-=x/value;
    }
    return x-sum;
}
int main ()
{
    T=(int)read();
    while(T--)
    {
        a=read();m=read();
        x=gcd(a,m);
        k1=a/x;k2=m/x;
        cout<<count_prime(k2+k1-1,k2)-count_prime(k1-1,k2)<<endl;
    }
    return 0;
}

  C

· Give you two strings

s, t, sequences required every time you use a string configuration t s, the number of the least expensive.

 

Set P R & lt E [ i ] represents the letter i i earliest occurrence position, S U F [ i ] [ J ]  represents represents the first i the i-bit characters, letters J J earliest position, this can be O ( 26 is n- ) O (26n) out pretreatment
then repeated directly above the cross-hop around it

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int maxl=100010;
int T;
char s[maxl],t[maxl];
int pre [30], suf [maxl] [30]; // pre (i) i represents the character first appeared position, SUF (i, j) in the i represents the character, the character first appeared position j 
int main ()
{
    T=read();
    while(T--)
    {
        mem(pre,42);mem(suf,42);
        scanf("%s%s",s,t);
        int l1=strlen(s),l2=strlen(t),cnt=0,ok=0;
        for(int i=0;i<l1;i++)pre[s[i]-'a']=min(pre[s[i]-'a'],i);
        for(int i=0;i<l1-1;i++)suf[i][s[i+1]-'a']=i+1;
        for(int i=l1-1;i>=0;i--)
            for(int j=0;j<26;j++)suf[i][j]=min(suf[i][j],suf[i+1][j]);
        for(int i=0;i<l2;)
        {
            ++cnt;
            int pos=pre[t[i]-'a'];i++;
            if(pos>=l1){ok=1;break;}
            while(suf[pos][t[i]-'a']<l1)pos=suf[pos][t[i]-'a'],i++;
        }
        if(!ok)printf("%d\n",cnt);
        else printf("%d\n",-1);
    }
    return 0;
}

  B

True breakthrough in ultra-long card, first of all give you a string composed of 01, you will be able to continue to use this string copy and paste an infinitely long string, the number 0 to ask you by how many prefixes can satisfy lose 1 is equal to the number given x

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<queue>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
typedef long long LL;
typedef pair<int,int> PII;
#define X first
#define Y second
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    return x*f;
}
const int maxn=100010;
int T,n,x,p0[maxn],p1[maxn],pre[maxn],MAX;
char s[maxn];
int main ()
{
    T=read();
    while(T--)
    {
        Mem (P0,0); mem (Pl,0); mem (Pray, 0);
        n=read();x=read();
        int cnt=0;
        scanf("%s",s+1);
        for(int i=1;i<=n;i++)p0[i]=p0[i-1]+(s[i]=='0'),p1[i]=p1[i-1]+(s[i]=='1'),pre[i]=p0[i]-p1[i];
        if(x==0)cnt=1;
        if(pre[n])
        {
            for(int i=1;i<=n;i++)if((x-pre[i])%pre[n]==0 && (x-pre[i])/pre[n]>=0)cnt++;
        }
        else
        {
            for(int i=0;i<=n;i++)if(x==pre[i])cnt++;
        }
        if(!pre[n] && cnt)printf("-1\n");
        else printf("%d\n",cnt);
    }
    return 0;
}

  

 

Guess you like

Origin www.cnblogs.com/hgangang/p/12244476.html