2018 徐州网赛

A .

After Incident, a feast is usually held in Hakurei Shrine. This time Reimu asked Kokoro to deliver a Nogaku show during the feast. To enjoy the show, every audience has to wear a Nogaku mask, and seat around as a circle.

There are N guests Reimu serves. Kokoro has 2k2^k2k masks numbered from 0,1,⋯,0,1,\cdots,0,1,, 2k−12^k - 12k1, and every guest wears one of the masks. The masks have dark power of Dark Nogaku, and to prevent guests from being hurt by the power, two guests seating aside must ensure that if their masks are numbered iii and jjj , then iii XNOR jjj must be positive. (two guests can wear the same mask). XNOR means ~(iii^jjj) and every number has kkk bits. (111 XNOR 1=11 = 11=1, 000 XNOR 0=10 = 10=1, 111 XNOR 0=00 = 00=0)

You may have seen 《A Summer Day's dream》, a doujin Animation of Touhou Project. Things go like the anime, Suika activated her ability, and the feast will loop for infinite times. This really troubles Reimu: to not make her customers feel bored, she must prepare enough numbers of different Nogaku scenes. Reimu find that each time the same guest will seat on the same seat, and She just have to prepare a new scene for a specific mask distribution. Two distribution plans are considered different, if any guest wears different masks.

In order to save faiths for Shrine, Reimu have to calculate that to make guests not bored, how many different Nogaku scenes does Reimu and Kokoro have to prepare. Due to the number may be too large, Reimu only want to get the answer modules 1e9+71e9+71e9+7 . Reimu did never attend Terakoya, so she doesn't know how to calculate in module. So Reimu wishes you to help her figure out the answer, and she promises that after you succeed she will give you a balloon as a gift.

Input

First line one number TTT , the number of testcases; (T≤20)(T \le 20)(T20) .

Next TTT lines each contains two numbers, NNN and k(0<N,k≤1e6)k(0<N, k \le 1e6)k(0<N,k1e6) .

Output

For each testcase output one line with a single number of scenes Reimu and Kokoro have to prepare, the answer modules 1e9+71e9+71e9+7 .

样例输入

2
3 1
4 2

样例输出

2
84

题意 : 给你一个 n 表示一个环的大小为 n , 再给你一个 k 表示可选择的数字 2^k-1 种,问最终的方案数是多少?
思路分析 :

 

代码示例 :
#define ll long long
const ll maxn = 1e6+5;
const ll mod = 1e9+7;

ll n, k;
ll qw(ll a, ll b){
    ll res = 1;
    
    while(b){
        if (b&1) res = res*a%mod;
        a = a*a%mod;
        b >>= 1;
    }
    return res;
}
ll num;

ll dfs(ll n){
    if (n == 1) return num;
    if (n == 2) return num*(num-1)%mod;
    ll ans = 0;
    ans += num*(num-2)%mod*qw(num-1, n-2)%mod;
    ans %= mod;
    ans += dfs(n-2);
    ans %= mod;
    
    return ans;
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    ll t;
    
    cin >> t;
    while(t--){
        cin >> n >> k;
        num = qw(2, k);
        printf("%lld\n", dfs(n));
    }
    return 0;
}

 还有一种 dp 的解法,弱表示根本想不到...   点~

dp[i][0] 表示到达 i 位置时,与首位置相同的方案数

dp[i][1] 表示到达 i 位置时,与首位置异或全为 1 的方案数

dp[i][2] 表示到达 i 位置时,均不是以上两种情况的方案数

dp[i][0] = dp[i-1][0] + dp[i-1][2];   

dp[i][1] = dp[i-1][1] + dp[i-1][2];

dp[i][2] = dp[i-1][0]*(sum-2) + dp[i][1]*(sum-2) + dp[i][2]*(sum-3) ;

代码示例 :

#define ll long long
const int maxn = 1e6+5;
const ll mod = 1e9+7;

ll n, k;
ll qw(ll a, ll b){
    ll res = 1;
    while(b){
        if (b&1) res = res*a%mod;
        a = a * a %mod;
        b >>= 1;
    }
    return res;
}
ll dp[maxn][3];

int main() { 
    int t;
    
    cin >> t;
    while(t--){
        cin >> n >> k;
        ll num = qw(2, k);
        
        dp[1][0] = num; dp[1][1] = dp[1][2] = 0;
        for(int i = 2; i <= n; i++){
            dp[i][0] = dp[i-1][0] + dp[i-1][2]; dp[i][0] %= mod;
            dp[i][1] = dp[i-1][1] + dp[i-1][2]; dp[i][1] %= mod;
            dp[i][2] = dp[i-1][0]*(num-2)%mod+dp[i-1][1]*(num-2)%mod+dp[i-1][2]*(num-3)%mod;
            dp[i][2] %= mod;
        }
        printf("%lld\n", (dp[n][0]+dp[n][2])%mod);
    }
    return 0;
}

 

 

B .

In a world where ordinary people cannot reach, a boy named "Koutarou" and a girl named "Sena" are playing a video game. The game system of this video game is quite unique: in the process of playing this game, you need to constantly face the choice, each time you choose the game will provide 1−31-313 options, the player can only choose one of them. Each option has an effect on a "score" parameter in the game. Some options will increase the score, some options will reduce the score, and some options will change the score to a value multiplied by −1-11 .

That is, if there are three options in a selection, the score will be increased by 111, decreased by 111, or multiplied by −1-11. The score before the selection is 888. Then selecting option 111 will make the score become 999, and selecting option 222 will make the score 777 and select option 333 to make the score −8-88. Note that the score has an upper limit of 100100100 and a lower limit of −100-100100. If the score is 999999 at this time, an option that makes the score +2+2+2 is selected. After that, the score will change to 100100100 and vice versa .

After all the choices have been made, the score will affect the ending of the game. If the score is greater than or equal to a certain value kkk, it will enter a good ending; if it is less than or equal to a certain value lll, it will enter the bad ending; if both conditions are not satisfied, it will enter the normal ending. Now, Koutarou and Sena want to play the good endings and the bad endings respectively. They refused to give up each other and finally decided to use the "one person to make a choice" way to play the game, Koutarou first choose. Now assume that they all know the initial score, the impact of each option, and the kkk, lll values, and decide to choose in the way that works best for them. (That is, they will try their best to play the ending they want. If it's impossible, they would rather normal ending than the ending their rival wants.)

Koutarou and Sena are playing very happy, but I believe you have seen through the final ending. Now give you the initial score, the kkk value, the lll value, and the effect of each option on the score. Can you answer the final ending of the game?

Input

The first line contains four integers n,m,k,ln,m,k,ln,m,k,l(1≤n≤10001\le n \le 10001n1000, −100≤m≤100-100 \le m \le 100100m100 , −100≤l<k≤100-100 \le l < k \le 100100l<k100 ), represents the number of choices, the initial score, the minimum score required to enter a good ending, and the highest score required to enter a bad ending, respectively.

Each of the next nnn lines contains three integers a,b,ca,b,ca,b,c(a≥0a\ge 0a0 , b≥0b\ge0b0 ,c=0c=0c=0 or c=1c=1c=1),indicates the options that appear in this selection,in which a=0a=0a=0 means there is no option to increase the score in this selection, a>0a>0a>0 means there is an option in this selection to increase the score by aaa ; b=0b=0b=0 means there is no option to decrease the score in this selection, b>0b>0b>0 means there is an option in this selection to decrease the score by bbb; c=0c=0c=0 means there is no option to multiply the score by −1-11 in this selection , c=1c=1c=1 means there is exactly an option in this selection to multiply the score by −1-11. It is guaranteed that a,b,ca,b,ca,b,c are not equal to 000 at the same time.

Output

One line contains the final ending of the game. If it will enter a good ending,print "Good Ending"(without quotes); if it will enter a bad ending,print "Bad Ending"(without quotes);otherwise print "Normal Ending"(without quotes).

样例输入1

3 -8 5 -5
3 1 1
2 0 1
0 2 1

样例输出1

Good Ending

样例输入2

3 0 10 3
0 0 1
0 10 1
0 2 1

样例输出2

Bad Ending

解法 : 点这里~

F .

Morgana is learning computer vision, and he likes cats, too. One day he wants to find the cat movement from a cat video. To do this, he extracts cat features in each frame. A cat feature is a two-dimension vector <xxx, yyy>. If xix_ixi = xjx_jxj and yiy_iyi = yjy_jyj, then <xix_ixi, yiy_iyi> <xjx_jxj, yjy_jyj> are same features.

So if cat features are moving, we can think the cat is moving. If feature <aaa, bbb> is appeared in continuous frames, it will form features movement. For example, feature <aaa , bbb > is appeared in frame 2,3,4,7,82,3,4,7,82,3,4,7,8, then it forms two features movement 2−3−42-3-4234 and 7−87-878 .

Now given the features in each frames, the number of features may be different, Morgana wants to find the longest features movement.

Input

First line contains one integer T(1≤T≤10)T(1 \le T \le 10)T(1T10) , giving the test cases.

Then the first line of each cases contains one integer nnn (number of frames),

In The next nnn lines, each line contains one integer kik_iki ( the number of features) and 2ki2k_i2ki intergers describe kik_iki features in ith frame.(The first two integers describe the first feature, the 333rd and 444th integer describe the second feature, and so on).

In each test case the sum number of features NNN will satisfy N≤100000N \le 100000N100000 .

Output

For each cases, output one line with one integers represents the longest length of features movement.

样例输入

1
8
2 1 1 2 2
2 1 1 1 4
2 1 1 2 2
2 2 2 1 4
0
0
1 1 1
1 1 1

样例输出

3
题意 : 求一个连续的区间内都出现的一个二维向量,问最长的长度时多少?
思路分析:由于是要比较两个元素的,我们可以直接去其进行 hash 一下,变成一个数字, 还挺好用
代码示例:
#define ll long long
#define ull unsigned long long

int n;
struct node
{
    ull x;
    int num;
    
    bool operator< (const node &v)const{
        if (x < v.x) return true;
        return false;
    }
};
set<node>s, f;
ull p = 19873;

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    int t;
    int k;
    ull x, y;
    
    cin >> t;
    while(t--){
        scanf("%d", &n);
        set<node>::iterator it;
        int ans = 1; 
        for(int i = 1; i <= n; i++){
            scanf("%d", &k);
            for(int j = 1; j <= k; j++){
                scanf("%llu%llu", &x, &y);
                ull num = x*p + y*11ull;
                it = f.find({num, 0}); 
                ans = max(ans, it->num+1);
                s.insert({num, it->num+1});
            }        
            f.clear(); f = s; s.clear();
        }  
        printf("%d\n", ans);
    }
    return 0;
}

 

G .

There's a beach in the first quadrant. And from time to time, there are sea waves. A wave ( xxx , yyy ) means the wave is a rectangle whose vertexes are ( 000 , 000 ), ( xxx , 000 ), ( 000 , yyy ), ( xxx , yyy ). Every time the wave will wash out the trace of former wave in its range and remain its own trace of ( xxx , 000 ) -> ( xxx , yyy ) and ( 000 , yyy ) -> ( xxx , yyy ). Now the toad on the coast wants to know the total length of trace on the coast after n waves. It's guaranteed that a wave will not cover the other completely.

Input

The first line is the number of waves n(n≤50000)n(n \le 50000)n(n50000).

The next nnn lines,each contains two numbers xxx yyy ,( 0<x0 < x0<x , y≤10000000y \le 10000000y10000000 ),the iii-th line means the iii-th second there comes a wave of ( xxx , yyy ), it's guaranteed that when 1≤i1 \le i1i , j≤nj \le njn ,xi≤xjx_i \le x_jxixj and yi≤yjy_i \le y_jyiyj don't set up at the same time.

Output

An Integer stands for the answer.

Hint:

As for the sample input, the answer is 3+3+1+1+1+1=103+3+1+1+1+1=103+3+1+1+1+1=10

样例输入

3
1 4
4 1
3 3

样例输出

10

题意 : 按顺序给出 n 个矩形,后出现的矩形会将前一个矩形所形成的痕迹所去掉,问最终的图形的痕迹是多大的?
思路分析 :
当只有一个图形的时候,选的边一定是横边和竖边,当有两个图形的时候,倒数第二个图形的 y 边所会产生的贡献为, 大于 x 中最大的 y 的边的差, x 边所会产生的贡献为大于 y 边中与最大的 x 边的差值
代码示例 :
#define ll long long
const ll maxn = 5e4+5;
#define pb push_back
#define lson k<<1
#define rson k<<1|1

ll n;
ll arr[maxn][2];
vector<ll>x, y;
struct node
{
    ll l, r;
    ll mx, my;
}t[maxn<<2];

void build(ll l, ll r, ll k){
    t[k].l = l, t[k].r = r;
    t[k].mx = t[k].my = 0;
    if (l == r) return;
    ll mid = (l+r)>>1;
    build(l, mid, lson);
    build(mid+1, r, rson);
}

ll query(ll l, ll r, ll pt, ll k) {
    if (l <= t[k].l && t[k].r <= r){
        if (pt == 1) return t[k].my;
        return t[k].mx;
    } 
    ll mid = (t[k].l+t[k].r)>>1;
    ll ans = 0;
    if (l <= mid) ans = max(ans, query(l, r, pt, lson));
    if (r > mid) ans = max(ans, query(l, r, pt, rson));
    return ans;
}

void pushup(ll k){
    t[k].mx = max(t[lson].mx, t[rson].mx);
    t[k].my = max(t[lson].my, t[rson].my);
}

void update(ll pos, ll num, ll pt, ll k){
    if (t[k].l == t[k].r){
        if (pt == 1) t[k].my = max(t[k].my, num);
        else t[k].mx = max(t[k].mx, num);
        return;
    }
    ll mid = (t[k].l + t[k].r) >> 1;
    if (pos <= mid) update(pos, num, pt, lson);
    else update(pos, num, pt, rson);
    pushup(k);
}

void solve() {
    ll ans = 0;
    for(ll i = n; i >= 1; i--){
        ll fx = lower_bound(x.begin(), x.end(), arr[i][0])-x.begin()+1;
        ll fy = lower_bound(y.begin(), y.end(), arr[i][1])-y.begin()+1;
        
        ll f1 = query(fx+1, n, 1, 1);
        ans += arr[i][1]-f1;
        update(fx, arr[i][1], 1, 1); 
        ll f2 = query(fy+1, n, 0, 1);
        ans += arr[i][0]-f2;
        update(fy, arr[i][0], 0, 1);
    }
    printf("%lld\n", ans);
}

int main() {
    cin >> n;
    for(ll i = 1; i <= n; i++) {
        scanf("%lld%lld", &arr[i][0], &arr[i][1]);
        x.pb(arr[i][0]), y.pb(arr[i][1]);
    }
    sort(x.begin(), x.end()); sort(y.begin(), y.end());
    x.erase(unique(x.begin(), x.end()), x.end());
    y.erase(unique(y.begin(), y.end()), y.end());
    
    build(1, n, 1);
    solve();
    return 0;
}

 

After the long vacation, the maze designer master has to do his job. A tour company gives him a map which is a rectangle. The map consists of N×MN \times MN×M little squares. That is to say, the height of the rectangle is NNN and the width of the rectangle is MMM. The master knows exactly how the maze is going to use. The tour company will put a couple in two different squares in the maze and make them seek each other. Of course,the master will not make them find each other easily. The only thing the master does is building some wall between some little squares. He knows in that way, wherever the couple is put, there is only one path between them. It is not a difficult thing for him, but he is a considerate man. He also knows that the cost of building every wall between two adjacent squares is different(Nobody knows the reason). As a result, he designs the maze to make the tour company spend the least money to build it.

Now, here's your part. The tour company knows you're the apprentice of the master, so they give you a task. you're given QQQ qustions which contain the information of where the couple will be put. You need to figure out the length of the shortest path between them.

However,the master doesn't tell you how he designs the maze, but he believes that you, the best student of himself, know the way. So he goes on vacation again.

Input

The first line of the input contains two integers NNN and MMM (1≤N,M≤5001 \le N,M \le 5001N,M500), giving the number of rows and columns of the maze.

The next N×MN \times MN×M lines of the input give the information of every little square in the maze, and their coordinates are in order of (1,1)(1,1)(1,1) , (1,2)(1,2)(1,2) ⋯\cdots(1,M)(1,M)(1,M) , (2,1)(2,1)(2,1) , (2,2)(2,2)(2,2) , ⋯\cdots⋯ , (2,M)(2,M)(2,M) , ⋯\cdots⋯ ,(N,M)(N,M)(N,M).

Each line contains two characters DDD and RRR and two integers aaa , bbb (0≤a,b≤20000000000 \le a,b \le 20000000000a,b2000000000 ), aaa is the cost of building the wall between it and its lower adjacent square, and bbb is the cost of building the wall between it and its right adjacent square. If the side is boundary, the lacking path will be replaced with X 000.

The next line contains an integer QQQ (1≤Q≤1000001 \le Q \le 1000001Q100000 ), which represents the number of questions.

The next QQQ lines gives four integers, x1x_1x1, y1y_1y1, x2x_2x2, y2y_2y2 ( 1≤x11 \le x_11x1 , x2≤Nx_2 \le Nx2N , 1≤y11 \le y_11y1 , y2≤My_2 \le My2M ), which represent two squares and their coordinate are (x1x_1x1 , y1y_1y1​) and (x2x_2x2​ , y2y_2y2​).

(xxx,yyy) means row xxx and column yyy.

It is guaranteed that there is only one kind of maze.

Output

For each question, output one line with one integer which represents the length of the shortest path between two given squares.

样例输入

3 3
D 1 R 9
D 7 R 8
D 4 X 0
D 2 R 6
D 12 R 5
D 3 X 0
X 0 R 10
X 0 R 11
X 0 X 0
3
1 1 3 3
1 2 3 2
2 2 3 1

样例输出

4
2
2

题意 : 给你一个 n*m 的图,会告诉你每个格子和它下面,右边边的权值,可以在相邻的两个格子之间修道路,最后要确保任意两个点之间只有一条通路,且修的道路的花费最小,再给你一些询问,询问任意两个点的距离是多少?

思路分析 : 水题啊,求个最大生成树,在树上求任意两点的 lca
代码示例:
#define ll long long
const int maxn = 1e6+5;
const int maxm = 3e5;

int n, m;
struct node
{
    int u, v;
    ll w;
    bool operator< (const node &v)const{
        return w > v.w;
    }
}arr[maxn];
int cnt = 1;
int s1, e1, s2, e2;
int f[maxm];
struct ff
{
    int to, cost;
};
vector<ff>ve[maxm];

int fid(int x){
    if (x != f[x]) f[x] = fid(f[x]);
    return f[x];
}

void krusal() {
    sort(arr+1, arr+cnt);
    
    for(int i = 1; i <= n*m; i++) f[i] = i;
    for(int i = 1; i < cnt; i++){
        int f1 = fid(arr[i].u);
        int f2 = fid(arr[i].v);
        
        if (f1 != f2) {
            f[f1] = f2;
            ve[arr[i].u].push_back({arr[i].v, arr[i].w});
            ve[arr[i].v].push_back({arr[i].u, arr[i].w}); 
        }
    }
}

int dep[maxm];
int grand[maxm][25], gw[maxm][25];
int N;

void dfs(int x, int fa){
    for(int i = 1; i <= N; i++) {
         grand[x][i] = grand[grand[x][i-1]][i-1];
         gw[x][i] = gw[x][i-1]+gw[grand[x][i-1]][i-1];
    }
    for(int i = 0; i < ve[x].size(); i++){
        int to = ve[x][i].to;
        int cost = ve[x][i].cost;
        if (to == fa) continue;
        
        dep[to] = dep[x]+1;
        grand[to][0] = x;
        gw[to][0] = 1;
        dfs(to, x);
    }
}

int lca(int a, int b){
    if (dep[a] > dep[b]) swap(a, b); // a zai b shang
    int ans = 0;
    for(int i = N; i >= 0; i--){
        if (dep[a] < dep[b] && dep[grand[b][i]] >= dep[a]) {
            ans += gw[b][i];
            b = grand[b][i];
        }
    }
    
    for(int i = N; i >= 0; i--){
        if (grand[a][i] != grand[b][i]){
            ans += gw[a][i];
            ans += gw[b][i];
            a = grand[a][i], b = grand[b][i];
        }
    }
    if (a != b) ans += 2;
    return ans;
}

int main() {
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    char a[5], b[5];
    ll x1, x2;
    
    scanf("%d%d", &n, &m);
    int k = 1;
    for(int i = 1; i <= n*m; i++) {
        scanf("%s%lld%s%lld", a, &x1, b, &x2);
        if (a[0] == 'D') arr[cnt++] = {k, k+n, x1};
        if (b[0] == 'R') arr[cnt++] = {k, k+1, x2};
        k++; 
    }
    krusal();
    dep[1] = 1; N = floor(log(n*m)/log(2));
    dfs(1, -1);
    
    int q;
    cin >> q;
    while(q--){
        scanf("%d%d%d%d", &s1, &e1, &s2, &e2);
        int n1 = m*(s1-1)+e1; int n2 = m*(s2-1)+e2; 
        printf("%d\n", lca(n1, n2));
    }
    return 0;
}

 

posted @ 2018-09-10 20:05  楼主好菜啊  阅读(345)  评论(0编辑  收藏  举报