National Day Training Day3 in Changle

Keywords: C++ less

T1 Dynamic Inverse Sequence Pair

subject

[Title Description]

This paper gives a permutation a with length n (the number of N occurs once in each sequence). Exchange two numbers at a time to find the result of the inverse logarithm% 2.

Inverse order pair: for two numbers a[i],a[j] (i < j), if a [i] > a [j], then (a[i],a[j]) is an inverse order pair.

[Input Format]

The first line has a positive integer n.

The next line, n, represents the given permutation a.

The next line has a positive integer q.

Next, line q, with two positive integers i and j per line, denotes the exchange of a[i] and a[j].

[Output Format]

The output is a total of q lines, representing the result of the inverse logarithm% 2 after each exchange.

[Input sample]

4
1 2 3 4
2
1 2
1 2

[Output sample]

1
0

[Data Scale]

For 60% of the data: n,q < 100;

For 80% of the data: n,q < 1000;

For 100% data: n,q < 100000.

analysis

Firstly, the result that the total number of inverse pairs of the initial sequence is redundant to 2 is obtained.

Each exchange of a[i] and a [j] (i < j) has the following effects on a[k]:

  • If K < i, a[k] is still ahead of a[i] and a[j], so the inverse logarithm of a[k] and a[i], a[j] is unchanged.
  • If k > j, as above, the inverse logarithm does not change.
  • If I < K < j, if a [i] < a [k], then the inverse logarithm + 1, otherwise - 1; if a [j] > a [k], then the inverse logarithm + 1, otherwise - 1,

But we only need to find the result of the remainder of the inverse logarithm to 2. We can find that the parity of the number of inverse logarithm pairs is independent of k.

In fact, it is only necessary to make the result ^ 1 of the total number of inverse pairs remaining to 2 at each exchange position (i=j is unchanged).

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
inline 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,q,a[100100],f[100100],temp;
void add(int x,int y)
{
    for(;x<=n;x+=(x&-x)) f[x]+=y;
}
int ask(int x)
{
    int ans=0;
    for(;x;x-=(x&-x)) ans+=f[x];
    return ans;
}
int main()
{
    //freopen("lyk.in","r",stdin);
    //freopen("lyk.out","w",stdout);
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    q=read();
    for(int i=n;i>=1;i--)
    {
        temp+=ask(a[i]-1);
        add(a[i],1);
    }
    temp&=1;
    for(int i=1;i<=q;i++)
    {
        int x=read(),y=read();
        if(x!=y) temp^=1;
        cout<<temp<<endl;
    }
    return 0;
}

 

 

 

 

 

Statistics of T2 Trees

subject

[Title Description]

A full binary tree with n points is given. The root node is 1, the left and right sub-nodes of the first point are 2i,2i+1, and the weight of the first point is a[i].

There are m inquiries. For each query, we give x,d, and get the point weight of all points whose distance to point x is d. If there are no qualified points, output 0.

The distance between two points is the number of edges of the shortest path between two points.

Make sure the final answer is in the int range.

[Input Format]

The first line has two positive integers n,m.

Next, n rows have a positive integer per row, and the number of rows I represents a[i].

Next, line m has two integers x and D for each line, representing a query.

[Output Format]

Output a line for each query to indicate the answer.

[Input sample]

7 3
13
7
2
9
5
6
8
1 3
4 2
3 1

[Output sample]

0
18
27

[Data Scale]

For 80% of the data, n < 1023, m < 1000.

For 100% data, n < 131071, m < 100000, n=2t-1, 1 < T < 17, a[i] < 30000.

analysis

For each query, we can use dfs to search the point whose distance from point x is d, and then make statistics.

Notice the relationship between each point. The visiting father is x < 1, the left son is x > 1, and the right son is x > 1 + 1.

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
inline 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=131073;
int n,m,a[N],dd,ans;
void dfs(int x,int d,int from)
{
    if(d>dd) return ;
    if(d==dd)
    {
        ans+=a[x];
        return ;
    }
    int y=x>>1;
    if(y>=1&&y!=from) dfs(y,d+1,x);
    y=x<<1;
    if(y<=n&&y!=from) dfs(y,d+1,x);
    if(y+1<=n&&y+1!=from) dfs(y+1,d+1,x);
}
int main()
{
    //freopen("dream.in","r",stdin);
    //freopen("dream.out","w",stdout);
    n=read(),m=read();
    a[1]=read();
    for(int i=2;i<=n;i++) a[i]=read();
    for(int i=1;i<=m;i++)
    {
        int x=read();
        dd=read(),ans=0;
        dfs(x,0,0);
        cout<<ans<<endl;
    }
    return 0;
}

 

 

 

 

 

T3 publicity column

subject

[Title Description]

There is a large rectangular billboard with height and width of h and m respectively. Propaganda boards are places where announcements are posted. At first, they are empty, but after that, announcements are put up one by one.

There are n notices. The height of each notice is one unit length. The width of the notice on the first post is w[i].

Every time a notice is posted, it is always posted in the highest place that can be posted. If there are more than one possible place, it is posted on the left.

Given the height and width of the bulletin board, your task is to find out what line each bulletin is posted on.

[Input Format]

The first three integers, h, m and n(1 < m < 109; 1 < h < n < 200000), indicate the size of the propaganda board and the number of posters.

Next n lines denote w[i] (1 < w[i] < 109).

[Output Format]

An integer per line represents the answer. If the first notice is not posted anywhere, output - 1.

[Input sample]

3 5 5
2
4
3
3
3

[Output sample]

1
2
1
3
-1

[Data Scale]

For 20% of the data, n=1.

For 40% of the data, n,m < 500.

For 70% of the data, n < 2000.

For 90% of the data, n is less than 50000.

For 100% of the data, n is less than 200000.

analysis

Use c[i] to indicate how long is left on line I.

Maintain the maximum value of the interval of c[i] with the segment tree.

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
inline 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 h,m,n,c[800100];
int w;
void build(int p,int l,int r)
{
    c[p]=m;
    if(l==r) return ;
    int mid=(l+r)>>1;
    build(p*2,l,mid),build(p*2+1,mid+1,r);
}
int ask(int p,int l,int r)
{
    if(l==r)
    {
        c[p]-=w;
        return l;
    }
    int mid=(l+r)>>1;
    if(c[p*2]>=w)
    {
        int temp=ask(p*2,l,mid);
        c[p]=max(c[p*2+1],c[p*2]);
        return temp;
    }
    else
    {
        int temp=ask(p*2+1,mid+1,r);
        c[p]=max(c[p*2+1],c[p*2]);
        return temp;
    }
}
int main()
{
    //freopen("billboard.in","r",stdin);
    //freopen("billboard.out","w",stdout);
    h=read(),m=read(),n=read();
    build(1,1,h);
    for(int i=1;i<=n;i++)
    {
        w=read();
        if(w>c[1])
        {
            cout<<"-1"<<endl;
            continue;
        }
        cout<<ask(1,1,h)<<endl;
    }
    return 0;
}

 

 

 

 

 

T4 planting trees

subject

[Title Description]

You have to plant trees on an endless road.

You want to plant three kinds of trees: strawberry, watermelon and potato.

Given three positive integers A,B,C, you can choose three integers x,y,z, and then:

  • In position... X-2A, x-A, x, x+A, x+2A,... One strawberry tree was planted.
  • In position... Y-2B, y-B, y, y, y + B, y + 2B,... One watermelon tree was planted.
  • In position... Z-2C, z-C, z, z+C, z+2C,... One potato tree was planted.

If you want to maximize the distance between the nearest two trees, please output the maximum distance.

[Input Format]

Multiple sets of test data for each test point.

Each group of data is entered in a row A,B,C.

No data array is given. You can type in this way:

while (scanf("%d%d%d", &A, &B, &C) == 3)

{

       ......

}

[Output Format]

Output a line for each query to indicate the answer.

[Input sample]

1 5 8
3 3 6
2000 2000 2000
999 999 999
233 233 233
100 100 100
40 30 20

[Output sample]

0
1
666
333
77
33
5

[Data Scale]

For 100% data, 1 < A,B,C < 2000.

analysis

solve function is used to find the minimum distance between two or three trees, and then the maximum can be found.

The proof process is troublesome and Ben's number theory is not very good, so we will not give a detailed proof.

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
int a,b,c,x,y,z,ans;
int gcd(int x,int y)
{
    if(y==0) return x;
    return gcd(y,x%y);
}
int solve(int a,int b,int x,int y)
{
    int g=gcd(a,b);
    int t=(x-y)%g;
    if(t<0) t+=g;
    return min(t,g-t);
}
int main()
{
    while(cin>>a>>b>>c)
    {
        ans=0;
        for(y=0;y<b;y++)
            for(z=0;z<c;z++)
            {
                int temp;
                temp=min(solve(a,b,0,y),min(solve(b,c,y,z),solve(a,c,0,z)));
                ans=max(ans,temp);
            }
        cout<<ans<<endl;
    }
    return 0;
}

Posted by Archbob on Sun, 06 Oct 2019 17:32:32 -0700