訓練賽20190304

D - Balanced Lineup

For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.

Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤ height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.

Input

Line 1: Two space-separated integers, N and Q
Lines 2.. N+1: Line i+1 contains a single integer that is the height of cow i 
Lines N+2.. NQ+1: Two integers A and B (1 ≤ A ≤ B ≤ N), representing the range of cows from A to B inclusive.

Output

Lines 1.. Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.

Sample Input

6 3
1
7
3
4
2
5
1 5
4 6
2 2

Sample Output

6
3
0

根據題意可得知這個題就是給出N個數,多次詢問在一個範圍內,最大值和最小值的差,很明顯的一個RMQ模板題,當然也有大佬用線段樹做了。。。RMQ可以看一下我的這個博客

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define exp 1e-8
#define mian main
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define pb push_back
#define PI  acos(-1.0)
#define inf 0x3f3f3f3f
#define w(x) while(x--)
#define int_max 2147483647
#define lowbit(x) (x)&(-x)
#define gcd(a,b) __gcd(a,b)
#define pq(x)  priority_queue<x>
#define ull unsigned long long
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define pl(a,n) next_permutation(a,a+n)
#define ios ios::sync_with_stdio(false)
#define met(a,x) memset((a),(x),sizeof((a)))
using namespace std;
const int N=1e5+10;
int n,q;
int maxn[N][25],minx[N][25];
void rmq(int n)
{
    for(int i=1;i<20;i++){
        for(int j=1;j+(1<<i)-1<=n;j++){
            maxn[j][i]=max(maxn[j][i-1],maxn[j+(1<<(i-1))][i-1]);
            minx[j][i]=min(minx[j][i-1],minx[j+(1<<(i-1))][i-1]);
        }
    }
}
int main()
{
    while(~sc(n)){
        scanf("%d",&q);
        for(int i=1;i<=n;i++){
            sc(maxn[i][0]);
            minx[i][0]=maxn[i][0];
        }
        rmq(n);
        int l,r;
        while(q--){
            scanf("%d%d",&l,&r);
            int k=(int)(log(r-l+1.0)/log(2.0));
        int Maxn=max(maxn[l][k],maxn[r-(1<<k)+1][k]);
        int Minx=min(minx[l][k],minx[r-(1<<k)+1][k]);
        printf("%d\n",Maxn-Minx);
        }
    }
}

F - 敵兵佈陣

C國的死對頭A國這段時間正在進行軍事演習,所以C國間諜頭子Derek和他手下Tidy又開始忙乎了。A國在海岸線沿直線佈置了N個工兵營地,Derek和Tidy的任務就是要監視這些工兵營地的活動情況。由於採取了某種先進的監測手段,所以每個工兵營地的人數C國都掌握的一清二楚,每個工兵營地的人數都有可能發生變動,可能增加或減少若干人手,但這些都逃不過C國的監視。 
中央情報局要研究敵人究竟演習什麼戰術,所以Tidy要隨時向Derek彙報某一段連續的工兵營地一共有多少人,例如Derek問:“Tidy,馬上彙報第3個營地到第10個營地共有多少人!”Tidy就要馬上開始計算這一段的總人數並彙報。但敵兵營地的人數經常變動,而Derek每次詢問的段都不一樣,所以Tidy不得不每次都一個一個營地的去數,很快就精疲力盡了,Derek對Tidy的計算速度越來越不滿:"你個死肥仔,算得這麼慢,我炒你魷魚!”Tidy想:“你自己來算算看,這可真是一項累人的工作!我恨不得你炒我魷魚呢!”無奈之下,Tidy只好打電話向計算機專家Windbreaker求救,Windbreaker說:“死肥仔,叫你平時做多點acm題和看多點算法書,現在嚐到苦果了吧!”Tidy說:"我知錯了。。。"但Windbreaker已經掛掉電話了。Tidy很苦惱,這麼算他真的會崩潰的,聰明的讀者,你能寫個程序幫他完成這項工作嗎?不過如果你的程序效率不夠高的話,Tidy還是會受到Derek的責罵的. 

Input

第一行一個整數T,表示有T組數據。 
每組數據第一行一個正整數N(N<=50000),表示敵人有N個工兵營地,接下來有N個正整數,第i個正整數ai代表第i個工兵營地裏開始時有ai個人(1<=ai<=50)。 
接下來每行有一條命令,命令有4種形式: 
(1) Add i j,i和j爲正整數,表示第i個營地增加j個人(j不超過30) 
(2)Sub i j ,i和j爲正整數,表示第i個營地減少j個人(j不超過30); 
(3)Query i j ,i和j爲正整數,i<=j,表示詢問第i到第j個營地的總人數; 
(4)End 表示結束,這條命令在每組數據最後出現; 
每組數據最多有40000條命令 

Output

對第i組數據,首先輸出“Case i:”和回車, 
對於每個Query詢問,輸出一個整數並回車,表示詢問的段中的總人數,這個數保持在int以內。 

Sample Input

1
10
1 2 3 4 5 6 7 8 9 10
Query 1 3
Add 3 6
Query 2 7
Sub 10 2
Add 6 3
Query 3 10
End 

Sample Output

Case 1:
6
33
59

這也是個樹狀數組的模板題,而且這個題我之前做過。。。

這算一個單點修改,區間查詢,算是樹狀數組裏最簡單的一種題型了,也可以看一下我的這個博客

#include<bits/stdc++.h>
#define exp 1e-8
#define mian main
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define pb push_back
#define PI  acos(-1.0)
#define inf 0x3f3f3f3f
#define w(x) while(x--)
#define int_max 2147483647
#define lowbit(x) (x)&(-x)
#define gcd(a,b) __gcd(a,b)
#define pq(x)  priority_queue<x>
#define ull unsigned long long
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define pl(a,n) next_permutation(a,a+n)
#define ios ios::sync_with_stdio(false)
#define met(a,x) memset((a),(x),sizeof((a)))
using namespace std;
const int N=1e5+10;
int n,c[N];
void update(int i,int val)
{
    while(i<=n){
        c[i]+=val;
        i+=lowbit(i);
    }
}
int sum(int i)
{
    int ans=0;
    while(i>0){
        ans+=c[i];
        i-=lowbit(i);
    }
    return ans;
}
int main()
{
    int t;
    sc(t);
    for(int i=1;i<=t;i++){
        sc(n);
        met(c,0);
        int x;
        for(int j=1;j<=n;j++){
            sc(x);
            update(j,x);
        }
                char p[10];
        printf("Case %d:\n",i);
        scanf("%s",p);
        int y;
        while(p[0]!='E'){
            scanf("%d%d",&x,&y);
            if(p[0]=='A')
                update(x,y);
            else if(p[0]=='S')
                update(x,-y);
            else
                printf("%d\n",sum(y)-sum(x-1));
            scanf("%s",&p);
        }
    }
}

G - Oulipo

 

The French author Georges Perec (1936–1982) once wrote a book, La disparition, without the letter 'e'. He was a member of the Oulipo group. A quote from the book:

Tout avait Pair normal, mais tout s’affirmait faux. Tout avait Fair normal, d’abord, puis surgissait l’inhumain, l’affolant. Il aurait voulu savoir où s’articulait l’association qui l’unissait au roman : stir son tapis, assaillant à tout instant son imagination, l’intuition d’un tabou, la vision d’un mal obscur, d’un quoi vacant, d’un non-dit : la vision, l’avision d’un oubli commandant tout, où s’abolissait la raison : tout avait l’air normal mais…

Perec would probably have scored high (or rather, low) in the following contest. People are asked to write a perhaps even meaningful text on some subject with as few occurrences of a given “word” as possible. Our task is to provide the jury with a program that counts these occurrences, in order to obtain a ranking of the competitors. These competitors often write very long texts with nonsense meaning; a sequence of 500,000 consecutive 'T's is not unusual. And they never use spaces.

So we want to quickly find out how often a word, i.e., a given string, occurs in a text. More formally: given the alphabet {'A', 'B', 'C', …, 'Z'} and two finite strings over that alphabet, a word W and a text T, count the number of occurrences of W in T. All the consecutive characters of W must exactly match consecutive characters of T. Occurrences may overlap.

Input

The first line of the input file contains a single number: the number of test cases to follow. Each test case has the following format:

  • One line with the word W, a string over {'A', 'B', 'C', …, 'Z'}, with 1 ≤ |W| ≤ 10,000 (here |W| denotes the length of the string W).
  • One line with the text T, a string over {'A', 'B', 'C', …, 'Z'}, with |W| ≤ |T| ≤ 1,000,000.

Output

For every test case in the input file, the output should contain a single number, on a single line: the number of occurrences of the word W in the text T.

Sample Input

3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN

Sample Output

1
3
0

題意:給定一個串t,和一個串s,問t在s中可以出現過幾次。

也是一個KMP的模板,學習KMP的話tyk在羣裏發的視頻就不錯......

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define exp 1e-8
#define mian main
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define pb push_back
#define PI  acos(-1.0)
#define inf 0x3f3f3f3f
#define w(x) while(x--)
#define int_max 2147483647
#define lowbit(x) (x)&(-x)
#define gcd(a,b) __gcd(a,b)
#define pq(x)  priority_queue<x>
#define ull unsigned long long
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define pl(a,n) next_permutation(a,a+n)
#define ios ios::sync_with_stdio(false)
#define met(a,x) memset((a),(x),sizeof((a)))
using namespace std;
const int N=1e5+10;
int next1[N],l1,l2,ans;
char str1[1000001],str2[10001];
void getnext()
{
	int i = 0, j = -1;
	next1[i] = j;
	while(i < l2) {
		if(j == -1 || str2[i] == str2[j]) {
			++i; ++j;
            next1[i] = j;
		}
		else j = next1[j];
	}
}
int kmp()
{
    getnext();
    int i=0;
    int j=0;
    int ans=0;
    while(i<l1){
        if(j==-1||str1[i]==str2[j]){
            i++;
            j++;
        }
        else j=next1[j];
        if(j==l2){
           // j=0;
            ans++;
            //i--;
        }
    }
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--){
            ans=0;
        scanf("%s%s",str2,str1);
        l1=strlen(str1);
        l2=strlen(str2);
        printf("%d\n",kmp());
    }
}

H - Power Strings

Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the empty string) and a^(n+1) = a*(a^n).

Input

Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.

Output

For each s you should print the largest n such that s = a^n for some string a.

Sample Input

abcd
aaaa
ababab
.
Sample Output
1
4
3

Hint

This problem has huge input, use scanf instead of cin to avoid time limit exceed.

 

題意:給出一個字符串s,找由它的幾個最小循環子串能夠組成字符串s?

這個題如果暴力的話顯然很容易t掉,這裏我們可以用到next數組了,next數組的意義是什麼呢?

next[i]代表到以i位置截止的s串(不加第一個字符)與s串的前綴的最大公共串。

那麼len(長度)-next[len]即爲最小循環節,然後直接判斷即可

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define exp 1e-8
#define mian main
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define pb push_back
#define PI  acos(-1.0)
#define inf 0x3f3f3f3f
#define w(x) while(x--)
#define int_max 2147483647
#define lowbit(x) (x)&(-x)
#define gcd(a,b) __gcd(a,b)
#define pq(x)  priority_queue<x>
#define ull unsigned long long
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define pl(a,n) next_permutation(a,a+n)
#define ios ios::sync_with_stdio(false)
#define met(a,x) memset((a),(x),sizeof((a)))
using namespace std;
const int N=1e5+10;
int next1[N],l1,l2,ans;
char str1[1000001],str2[10001];
void getnext()
{
	int i = 0, j = -1;
	next1[i] = j;
	while(i < l2) {
		if(j == -1 || str2[i] == str2[j]) {
			++i; ++j;
            next1[i] = j;
		}
		else j = next1[j];
	}
}
int kmp()
{
    getnext();
    int i=0;
    int j=0;
    int ans=0;
    while(i<l1){
        if(j==-1||str1[i]==str2[j]){
            i++;
            j++;
        }
        else j=next1[j];
        if(j==l2){
           // j=0;
            ans++;
            //i--;
        }
    }
    return ans;
}
int main()
{
    int t;
    sc(t);
    while(t--){
            ans=0;
        scanf("%s%s",str2,str1);
        l1=strlen(str1);
        l2=strlen(str2);
        printf("%d\n",kmp());
    }
}

L - 搬果子

果園裏面有n堆果子,每堆果子有xi個,每個果子的重量爲1,小明每次把i,j兩堆果子移成一堆,需要花費的體力爲xi+xj。最後移成一堆,求最小花費體力值。
其中1<=n<=10000,1<=m<=10000。均爲正整數。

Input

    每組數據第一行輸入一個正整數n,表示有n堆果子。

    接下來一行有n個正整數,表示每堆果子的重量。

    輸入以EOF結尾。

Output

    每組數據單獨一行,輸出所花費的最小體力值。

Sample Input

3

1 2 9

5

1 3 9 18 30

Sample Output

15

109

水題,用優先隊列做做即可,一開始把它想成區間dp了,尷尬。。

#include<bits/stdc++.h>
#define exp 1e-8
#define mian main
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define pb push_back
#define PI  acos(-1.0)
#define inf 0x3f3f3f3f
#define w(x) while(x--)
#define int_max 2147483647
#define lowbit(x) (x)&(-x)
#define gcd(a,b) __gcd(a,b)
#define pq(x)  priority_queue<x>
#define ull unsigned long long
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define pl(a,n) next_permutation(a,a+n)
#define ios ios::sync_with_stdio(false)
#define met(a,x) memset((a),(x),sizeof((a)))
using namespace std;
int n,a[10001];
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
    while(~sc(n)){
        met(a,0);
        for(int i=1;i<=n;i++){
            sc(a[i]);
            q.push(a[i]);
        }
        int p1,p2;
        int ans=0;
        while(!q.empty()){
            p1=q.top();
            q.pop();
            if(q.empty()){
                printf("%d\n",ans);
                break;
            }
            p2=q.top();
            q.pop();
            p1+=p2;
            ans+=p1;
            q.push(p1);
        }

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章