Changle National training Day3

T1 dynamic reverse order

topic

Description [title]

Given a length of n are arranged a (1 ~ n in which n number of columns in each occurrence 1). Two numbers each exchange, reverse seeking results for a 2%.

Reverse pair: two numbers a [i], a [j] (i <j), if a [i]> a [j], then (a [i], a [j]) is a reverse order .

[Input Format]

The first line of a positive integer n.

Next, a line number n, represents a given arrangement.

The next line a positive integer q.

Next q lines of two positive integers i, j, represents the exchange a [i] and a [j].

[Output format]

Total output line q represents 2% results for a reverse after each exchange.

[Sample input]

4
1 2 3 4
2
1 2
1 2

[Sample Output]

1
0

[Data] scale

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

For 80% of data: n, q≤1000;

To 100% of the data: n, q≤100000.

Resolve

Obtaining first reverse original sequence result in the total number of modulo 2.

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

  • If k <i, a [k] is still in a [i] and a [j] in front, so that a [k] and a [i], a [j] generated by the reverse change log;
  • If k> j, ibid., Reverse logarithmic unchanged;
  • If i <k <j, if a [i] <a [k], the number of reverse +1 or -1 ,; If a [j]> a [k], the number of reverse + 1, or - 1,

And we only need to find the number of results for reverse modulo 2 can be found on the reverse has nothing to do with the parity of the number k.

In fact, only at each switching position, so that the total number of the results of reverse modulo 2 ^ 1 can (i = j is the time constant).

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;
}
View Code

 

 

 

 

 

T2 tree statistics

topic

Description [title]

N points are given a full binary tree, a root node, the child node about the i-th first point, respectively 2i, 2i + 1 points, the i th weight-point value a [i].

There are m interrogation. X is given for each interrogation, d, to find the point x is the distance of all points of the point d and the right. If you meet the conditions do not exist, output 0.

Two i.e. the distance between two points of the number of edges in the shortest path.

Ensure that the final answer in the int range.

[Input Format]

The first line of two positive integers n, m.

The next n lines each a positive integer, denotes the number of i-th row a [i].

The next two rows each integers m rows x, d, represents a challenge.

[Output format]

For each query output line represents the answer.

[Sample input]

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

[Sample Output]

0
18
27

[Data] scale

For 80% of data, n≤1023, m≤1000.

To 100% of the data, n≤131071, m≤100000, n-2 = T -1,1≤t≤17, A [I] ≤ 30000.

Resolve

For each inquiry, with the dfs search and point to point distance x d, the statistics can be.

Note that the relationship between each point, visit the father is x << 1, the left son is x >> 1, the right son is x >> 1 + 1, what about his son sentenced to special number can not be greater than n, otherwise it will RE.

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;
}
View Code

 

 

 

 

 

T3 billboards

topic

Description [title]

There is a large rectangular billboards, height and width respectively, and h m. Bulletin boards are used to post notices of the place, initially, billboards are empty, but then notices will be put up one by one.

There are n sheets notice, a notice of each one unit length is high, the i-th post notices on a width of w [i].

Each time you post, you can always post the notices posted at the highest place and, if there is more viable place to select the left post.

Given billboards height and width, your task is to find signs posted in each of the first few lines.

[Input Format]

The first row of three integers, h, m, and n-(1≤m≤10 . 9 ; 1≤h≤n≤200000), indicating the size and number of billboards post notices.

The next line indicates n W [I] (1 ≤ W [I] ≦ 10 . 9 ).

[Output format]

Each row represents an integer answer. If the i-th notices nowhere to stick, output -1.

[Sample input]

3 5 5
2
4
3
3
3

[Sample Output]

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≤50000.

To 100% of the data, n≤200000.

Resolve

With c [i] denotes the i-th row length much left.

Maintenance c [i] to a maximum interval 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;
}
View Code

 

 

 

 

 

T4 trees

topic

Description [title]

You have to plant trees on an infinitely long road.

You want to plant 3 trees, are the strawberry tree, tree, watermelon, potato tree.

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

  • Position ..., x-2A, xA, x, x + A, x + 2A, ... are a kind of Strawberry Tree.
  • Position ..., y-2B, yB, y, y + B, y + 2B, ... are tree kinds of a watermelon.
  • Position ..., z-2C, zC, z, z + C, z + 2C, ... are tree kinds of a potato.

You want to maximize the nearest two trees in the distance, you output the maximum distance.

[Input Format]

Each test point multiple sets of test data.

Each data input line A, B, C.

It did not give the number of data sets, so you can enter:

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

{

       ……

}

[Output format]

For each query output line represents the answer.

[Sample input]

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

[Sample Output]

0
1
666
333
77
33
5

[Data] scale

To 100% of the data, 1≤A, B, C≤2000.

Resolve

To obtain the minimum value of the minimum distance between the three trees twenty-two with solve function, and then to find the maximum.

The proof is too much trouble, this number is not very good on konjac, do 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;
}
View Code

 

Guess you like

Origin www.cnblogs.com/I-Love-You-520/p/11619429.html