Changle Training Day6

Posted by 25lez25 on Sun, 28 Jul 2019 04:42:15 +0200

T1 sequence

subject

[Title Description]

[Input Format]

[Output Format]

[Data Scale]

As mentioned above.

analysis

As a T1, it's harder than T4.... Let me do... Here's how to solve the problem for Big Man:

I guess you guys don't understand when you read the solution (manual funny). I can't do anything with the code.

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
int read()
{
    int num=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        num=(num<<1)+(num<<3)+ch-'0';
        ch=getchar();
    }
    return num*w;
}
const int N=400100;
struct rec1{
    int w,pos,num;
}a[N];
struct rec2{
    int x,y,z,num;
}b[N];
struct rec3{
    int tot0;
    long long tot1,tot2;
    rec3 friend operator - (rec3 x,rec3 y)
    {
        return (rec3){x.tot0-y.tot0,x.tot1-y.tot1,x.tot2-y.tot2};
    }
};
int n,q;
long long sum[N*2][3],ans[N];
bool bj[N];
bool cmp1(rec1 x,rec1 y)
{
    return x.w<y.w;
}
bool cmp2(rec2 x,rec2 y)
{
    return x.z<y.z;
}
void insert(int x,int y)
{
    long long g=1ll*y*y;
    for(int i=x;i<=n;i+=(i&-i)) sum[i][0]++,sum[i][1]+=y,sum[i][2]+=g;
}
rec3 find(int x)
{
    rec3 tot=(rec3){0,0,0};
    for(int i=x;i;i-=(i&-i)) tot.tot0+=sum[i][0],tot.tot1+=sum[i][1],tot.tot2+=sum[i][2];
    return tot;
}
void put(long long x)
{
    if(!x){cout<<"0"<<endl;return ;}
    if(x<0) x=-x,cout<<"-";
    int b[20],lenb=0;
    while(x)
    {
        b[++lenb]=x%10;
        x/=10;
    }
    for(int i=lenb;i>=1;i--) cout<<(char)(b[i]+'0');
    cout<<endl;
}
int main()
{
    //freopen("sequence.in","r",stdin);
    //freopen("sequence.out","w",stdout);
    n=read(),q=read();
    for(int i=1;i<=n;i++) a[i].w=read(),a[i].pos=read(),a[i].num=i;
    sort(a+1,a+n+1,cmp1);
    for(int i=1;i<=q;i++) b[i].x=read(),b[i].y=read(),b[i].z=read(),b[i].num=i;
    sort(b+1,b+q+1,cmp2);
    int j=0;
    for(int i=1;i<=q;i++)
    {
        while(j+1<=n&&a[j+1].w<=b[i].z) insert(a[j+1].num,a[j+1].pos),j++;
        rec3 tot=find(b[i].y)-find(b[i].x-1);
        if(!tot.tot0){bj[b[i].num]=1;continue;}
        ans[b[i].num]=tot.tot2*tot.tot0-2*tot.tot1*tot.tot1+tot.tot1*tot.tot1;
    }
    for(int i=1;i<=q;i++)
        if(bj[i]) cout<<"empty"<<endl;
        else put(ans[i]);
    return 0;
    //fclose(stdin);
    //fclose(stdout);
}

 

 

 

 

 

T2 set

subject

[Title Description]

Given a reusable set, there is only one element 0 at the beginning. Then you can operate on several rounds, each of which you need to do one of the following three operations for each element x in the set:

1. Change x to x+1.

2. Splitting x into two non-negative integers y,z and satisfying x=y+z.

3. Do nothing.

In each round, each element in the set must perform one of the three operations mentioned above.

For a final set, your task is to determine how many rounds have been made at least.

[Input Format]

The first action is a positive integer n, which represents the final size of the set.

The second behavior is n non-negative integers, describing the elements in the set.

[Output Format]

Output a non-negative integer, the minimum number of rounds.

[Data Scale]

analysis

The only one of the four questions was sent a sub-question, which resulted in QAQ being misread.

Obviously, we should try to score as much as possible, and then try to add one.

It's obviously not easy to push from scratch. We might as well push backwards:

Every time the number that is not zero is subtracted by one, and zero is merged into two.

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
int read()
{
    int num=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        num=(num<<1)+(num<<3)+ch-'0';
        ch=getchar();
    }
    return num*w;
}
int n,a[1000100],cnt[1000100],maxn;
long long ans;
int main()
{
    //freopen("multiset.in","r",stdin);
    //freopen("multiset.out","w",stdout);
    n=read();
    for(int i=1;i<=n;i++)
    {
        a[i]=read();
        maxn=max(maxn,a[i]);
        cnt[a[i]]++;
    }
    for(int i=1;i<=maxn;i++)
    {
        ans++;
        cnt[0]=(cnt[0]+1)>>1;
        cnt[0]+=cnt[i];
    }
    for(;cnt[0]>1;cnt[0]=(cnt[0]+1)>>1) ans++;
    cout<<ans;
    return 0;
    //fclose(stdin);
    //fclose(stdout);
}

 

 

 

 

 

T3 Welcoming Ceremony

subject

[Title Description]

The teaching is mainly directed by City C. In order to meet the bishop, a group of people standing on both sides of the road wearing cultural shirts to meet the bishop, each shirt is printed with big letters.

The people on the other side put forward in turn "Welcome Welcome Welcome Welcome..." Big characters, but the leader suddenly found that the other side wearing the "teach" and "master" cultural shirt is not harmonious.

To briefly describe this disharmonious queue, we use "j" instead of "teaching" and "z" instead of "master". A sequence of "j" and "z" can describe the current queue.

In order to make the bishop as comfortable as possible, you have to adjust the queue so that there are as many "jz" substrings as possible. Each time you adjust, you can swap two people at any position, that is, two letters at any position in the sequence.

And because the Master is coming soon, and there is only enough time to make K adjustments at most (of course, not enough K adjustments), this question is handed over to you.

[Input Format]

Line 1 contains two positive integers, N and K, representing the sequence length and the maximum number of swaps.

Line 2 contains a string of length N, which consists of the letters "j" and "z", describing the sequence.

[Output Format]

Only one non-negative integer is included, and how many "jz" substrings can appear after adjusting up to K times.

[Data Scale]

For 10% of the data, N < 10;

For 30% of the data, K < 10;

For 40% of the data, N < 50;

For 100% data, there are N < 500, K < 100

analysis

It is also a dynamic programming, so that f[i][j][z] represents the first I characters, and has processed J'j'and Z'z'.

The boundary is f[0][0][0]=f[1][0][0]=0.

State transition equation:

1. No replacement: f[i][j][z]=f[i-1][j][z].

2. Change: If a[i-1] is'j', let u=0, otherwise u=1, if a[i] is'z', let v=0, otherwise v=1,

Because i f'j'or'z' had been processed before, the number of'j'and'z' would not have to be increased, otherwise, f[i][j][z]=f[i-2][j-u][z-v].

The final answer is the largest f[n][i][i](i=1-k).

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
int read()
{
    int num=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        num=(num<<1)+(num<<3)+ch-'0';
        ch=getchar();
    }
    return num*w;
}
int n,k,maxn,f[505][105][105],l1,l2,u,v;
char a[505];
int main()
{
    //freopen("welcome.in","r",stdin);
    //freopen("welcome.out","w",stdout);
    memset(f,0xcf,sizeof(f));
    f[0][0][0]=0,f[1][0][0]=0;
    n=read(),k=read();
    a[0]='z',a[n+1]='j';
    for(int i=1;i<=n;i++)
    {
        a[i]=getchar();
        if(a[i]=='j') l1++;
        else l2++;
    }
    l1=min(l1,k),l2=min(l2,k);
    for(int i=2;i<=n;i++)
    {
        if(a[i-1]=='j') u=0;
        else u=1;
        if(a[i]=='z') v=0;
        else v=1;
        for(int j=0;j<=l1;j++)
            for(int z=0;z<=l2;z++)
            {
                f[i][j][z]=f[i-1][j][z];//No change
                if(j-u>=0&&z-v>=0) f[i][j][z]=max(f[i][j][z],f[i-2][j-u][z-v]+1);//change 
            }
    }
    for(int i=0;i<=k;i++) maxn=max(maxn,f[n][i][i]);
    cout<<maxn;
    return 0;
    //fclose(stdin);
    //fclose(stdout);
}

 

 

 

 

 

T4 puzzle game

subject

[Title Description]

Little P and little R are playing a puzzle game. The game is played on a positive directed graph.

The role of small P control should be shortest from point A to point B, and the role of small R control should be shortest from point C to point D.

A player has two choices for each round, moving to an adjacent node or resting for one round.

If at some point, small P and small R are on the same node, then they can get a special reward, but at most they can only get one reward on each node.

Seek how many special awards you can get at most.

[Input Format]

The first row has two integers n and m representing the number of points and edges of a digraph.

Next, line m has three integers xi, yi, li for each line, indicating that there is an edge of li in length from Xi to yi.

The last line contains four integers A, B, C, D, describing the starting and ending points of small P and small R.

[Output Format]

Output of an integer indicates how many special rewards you can get at most. If small P can't reach point B or small R can't reach point D, output - 1.

[Data Scale]

For 30% of the data, n < 50 is satisfied.

For 60% of the data, it satisfies n < 1000, m < 5000.

For 100% data, it satisfies n < 50000, m < 200000, 1 < li < 500000000.

analysis

This problem is solved by dijkstra+topu four times. It's horrible. Let's not say, throw the big man's problem directly.

(1) Special reward points must be continuous

(2) if s - > x + (x,y) + Y - > t = s - > t, then (x,y) is on the shortest path from s to t

(3) All edges on the shortest path of A-> B, C-> D form a directed acyclic graph.

Finding the Shortest Path of A and C Starting on the Forward Graph

Finding the Shortest Path to B, D on the Reverse Graph

The shortest path can be dijkstra + priority queue

The edges on the shortest path A - > B, C - > D are selected as new graphs.

Finding the Longest Path for New Graph Topological Sorting+DP

Time complexity (MlogN)

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
using namespace std;
long long read()
{
    long long num=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        num=(num<<1)+(num<<3)+ch-'0';
        ch=getchar();
    }
    return num*w;
}
const int N=50010;
const int M=200010;
struct rec{
    int to,next;
    long long l;
}edge1[M],edge2[M];
int n,m,cnt,head1[N],head2[N],in[N],f[N],ans;
long long d1[N],d2[N],d3[N],d4[N];
bool vis[N];
void add1(int x,int y,int l)
{
    edge1[++cnt].to=y;
    edge1[cnt].l=l;
    edge1[cnt].next=head1[x];
    head1[x]=cnt;
    edge2[cnt].to=x;
    edge2[cnt].l=l;
    edge2[cnt].next=head2[y];
    head2[y]=cnt;
}
void add2(int x,int y)
{
    edge2[++cnt].to=y;
    edge2[cnt].next=head2[x];
    head2[x]=cnt;
}
void dijkstra(int t,long long *d,int *head,rec *edge)
{
    for(int i=1;i<=n;i++) d[i]=0x7f7f7f7f7f7f7f7f;
    memset(vis,false,sizeof(vis));
    priority_queue< pair<long long,int> > q;
    d[t]=0,q.push(make_pair(0,t));
    while(q.size())
    {
        int now=q.top().second;
        q.pop();
        if(vis[now]) continue;
        vis[now]=true;
        for(int i=head[now];i;i=edge[i].next)
        {
            int next=edge[i].to;
            long long l=edge[i].l;
            if(d[next]>d[now]+l)
            {
                d[next]=d[now]+l;
                q.push(make_pair(-d[next],next));
            }
        }
    }
}
void topu_sort()
{
    queue<int> q;
    for(int i=1;i<=n;i++)
        if(!in[i]) q.push(i);
    while(q.size())
    {
        int now=q.front();
        q.pop();
        for(int i=head2[now];i;i=edge2[i].next)
        {
            int next=edge2[i].to;
            f[next]=max(f[next],f[now]+1);
            ans=max(ans,f[next]);
            in[next]--;
            if(!in[next]) q.push(next);
        }
    }
}
int main()
{
    //freopen("game.in","r",stdin);
    //freopen("game.in","w",stdout);
    n=read(),m=read();
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        long long l=read();
        add1(x,y,l);
    }
    int a=read(),b=read(),c=read(),d=read(),k=0;
    dijkstra(a,d1,head1,edge1),dijkstra(b,d2,head2,edge2);
    dijkstra(c,d3,head1,edge1),dijkstra(d,d4,head2,edge2);
    if(d1[b]==0x7f7f7f7f7f7f7f7f||d3[d]==0x7f7f7f7f7f7f7f7f)
    {
        cout<<"-1";
        return 0;
    }
    for(int i=1;i<=n;i++)
        if(d1[i]+d2[i]==d1[b]&&d3[i]+d4[i]==d3[d])
        {
            k=1;
            break;
        }
    memset(edge2,0,sizeof(edge2));
    memset(head2,0,sizeof(head2));
    cnt=0;
    for(int i=1;i<=n;i++)
        for(int j=head1[i];j;j=edge1[j].next)
        {
            int next=edge1[j].to;
            if(d1[i]+d2[next]+edge1[j].l==d1[b]&&d3[i]+d4[next]+edge1[j].l==d3[d])
            {
                in[next]++;
                add2(i,next);
            }
        }
    topu_sort();
    cout<<ans+k;
    return 0;
    //fclose(stdin);
    //fclose(stdout);
}

Topics: Python Programming