10-3 National Day Sixth simulation game

Source: Internet
Author: User

T1 Cannon (Cannon)

Description

Makik once addicted to playing Mahjong, keen on the gun he recently began to fall in love with Chinese chess. Faced with a nxm chessboard, he could not help thinking: "Cannon" on this board, and any two "cannon" between the number of programs will not attack each other how many?

Description: Two cannons can attack each other, when and only if they are on the same row or column and exactly spaced one piece, i.e. "puffing out ge".

Since Makik cannot remember too much numbers, please tell him the answer to the 999983 modulo result.

Input

The input file contains a row of two integer n,m that represent the length and width of the board, respectively.

Output

The output is an integer that represents the result of the 999983999983 modulo of the scheme number.

Xjbdp

Vaguely remember is a Logu of the original problem, but did not do at the time.

At first I thought it was a math problem, and I thought I'd find DP. But the state will not set AH ...

Thanks for the puzzle:

Set \ (f[i][j][k]\) indicates that there are j columns in the front I row to place 1 cannons, and a k column to place 2 cannons.

According to the analysis of the problem can be known, in the same column or the same column can not put more than two guns, because three guns will start to attack each other.

So there are only three possible rows in each row, either no, or one, or two of them.

This is a very useful information that allows us to start writing state transitions.

Use the Push table method.

It is easy to come up with if i+1 can pass what is not put directly there I launch, this is the i+1 line does not shoot the case.

f[i+1][j][k]=(f[i+1][j][k]+f[i][j][k])%mod;

Can be launched by \ (f[i][j][k]\) the value of \ (f[i+1][j+1][k]\) , meaning that if there is a column in the first row of nothing, then you can put one on this column, which will make J plus 1, which is i+ 1 lines put a gun in the case.

if(m-j-k>=1)f[i+1][j+1][k]=(f[i+1][j+1][k]+f[i][j][k]*(m-j-k))%mod;

Can also be launched by \ (f[i][j][k]\) (f[i+1][j-1][k+1]\) case, meaning that if there are only 1 guns in the first row of the column, we can put a gun on this column to make it into two pieces, This is also the case of i+1 to put a gun.

if(j>=1)f[i+1][j-1][k+1]=(f[i+1][j-1][k+1]+f[i][j][k]*j)%mod;

The above three cases are for the case of line i+1 0 or 1 cannons.

There are also three cases where the first line of i+1 is 2 cannons.

So first, you can launch \ (f[i+1][j-2][k+2]\)from \ (f[i][j][k]\) , which means we can find two columns that have been put on a cannon, and put a cannon on each of these two columns, That would reduce the number of columns in a cannon by 2, and the number of two cannons plus 2.

if(j>=2)f[i+1][j-2][k+2]=(f[i+1][j-2][k+2]+f[i][j][k]*C(j))%mod;C(j)=C(j,2)

Can also be launched from \ (f[i][j][k]\) (f[i+1][j+2][k]\) means you can find two guns are not put on the column, and then put a gun in these two columns

if((m-j-k)>=2)f[i+1][j+2][k]=(f[i+1][j+2][k]+f[i][j][k]*C(m - j - k)) % mod;

You can also combine the above two, on the i+1 line on the new two guns a

if((m-k-j)>=1&&j>=1)f[i+1][j][k+1]=(f[i+1][j][k+1]+f[i][j][k]*(m-k-j)*j)%mod;

Oh yes, the final answer is \ (\sum_{j=0;j<=n}\sum_{k=0,k+j<=n}f[n][j][k]\).

At this point, the problem is solved.

Code

#include <iostream> #include <cstdio>using namespace std;const int Mod=9999973;inline int read () {int sum=0,f    = 1;    Char Ch=getchar (); while (ch< ' 0 ' | |        Ch> ' 9 ') {if (ch== '-') f=-1;    Ch=getchar ();        } while (ch>= ' 0 ' &&ch<= ' 9 ') {sum= (sum<<1) + (sum<<3) +ch-' 0 ';    Ch=getchar (); } return sum*f;} int C (int _) {return _* (_-1)/2;}    int N,m;long Long Ans;long long F[111][111][111];int main () {n=read ();    M=read (); f[0][0][0]=1;//There are 1 options for (int i=0;i<=n;i++) {for (int j=0;j<=m;j++) {for (int k=0;k+j<=m).                    ; k++) {if (F[i][j][k]) {f[i+1][j][k]= (f[i+1][j][k]+f[i][j][k])%mod;                    if (j>=1) f[i+1][j-1][k+1]= (f[i+1][j-1][k+1]+f[i][j][k]*j)%mod;                    if (m-j-k>=1) f[i+1][j+1][k]= (f[i+1][j+1][k]+f[i][j][k]* (m-j-k))%mod;                if (j>=2) f[i+1][j-2][k+2]= (F[i+1][j-2][k+2]+f[i][j][k]*c (j))%mod;    if ((m-j-k) >=2) f[i+1][j+2][k]= (F[i+1][j+2][k]+f[i][j][k]*c (M-j-k))% MoD;                if ((m-k-j) >=1&&j>=1) f[i+1][j][k+1]= (f[i+1][j][k+1]+f[i][j][k] * (M-k-J) * j)% MoD; }}}} for (int. i=0;i<=m;i++) {for (int j=0;j+i<=m;j++) {(ans+=f[n][i][j])%        =mod;    }} printf ("%lld\n", ans); return 0;}
T2 (Roll)

Description

After tired of playing chess, Makik came up with a look at the scenery. This time, he came to the MS mountain range. The MS mountain ranges from 11 to NN, and some of the peaks are connected with roads. The Makik, who was deeply attracted by the view, was paid to carry him to the top of the 1th peak, where he would begin his journey.

Makik don't like mountain climbing, but like to go down the mountain, because can roll. When the Makik on the I peak, if there is a road between the peaks I and J Mountain, and the height of the J peaks is not greater than the height of the mountain I, then he can go along this road from mountain I to the mountain of J. Makik also has a magical ability to walk back (rather than roll back) along the rolling path to the peaks that have been visited.

Makik want to visit as many peaks as possible, and also want to make the rolling distance as short as possible under this premise. Please tell me how many peaks he can visit at this time, how many roads should I need to roll?

Input

The first line of the input file contains two integers n,m the number of roads that represent the peaks.

The next line contains the number of \ (n\) , which in turn represents the height of each mountain.

After M-line, three integers per line x_i,y_i,z_i indicates that there is a Zi road between the two peaks of the Xi and Yi.

Output

Output a row of two integers representing the maximum number of peaks the Makik can visit and the shortest distance he needs to roll.

Original title Link: Rokua P2573 [SCOI2012] Ski https://www.luogu.org/problemnew/show/P2573

To pay attention to a problem, that is, rolling and walking is not the same, the problem is to be rolled away, so to go back to the answer does not contribute.

So try to draw one, you can find that we extend from the outset, because to ensure that the most points to reach, so we need to expand all the points that can be reached from the first, a search can solve the problem.

On this basis, we ask for the shortest distance, where the distance is the length of each side of our expansion process.

Just imagine, when we extend this edge, we must be rolling there, so we will definitely contribute to the answer.

I feel that the above is too messy, I need to say it again.

From the beginning, for all the points that can be expanded to the smallest spanning tree.

The minimum spanning tree cannot be directly obtained because some points cannot be reached because of the height limit, so the last sentence is all the points that can be extended to.

Guaranteed from high to low, so build edges based on the height comparison between two points. (High point to low to build one-way edge, with no edge to the same height)

Procedure step: Enter according to the height of the construction of the edge, starting from 1 wide search, mark each point can be reached, this time can be counted out the answer to the first question, then you can find the side of the MST built, and because to ensure that the point to reach the most, so in the side of the order to change the priority.

In this case, these three points are we can go to also should go to, but if the order of the side length, it is clear that there are two sides are connected to the same point, which does not meet our requirements of the minimum tree, if according to the height of the order, it can be very good first to traverse the point, and then to find the smallest Benquan

[In such cases, these three points are we can go to also should go to, but if the order of the side length, it is clear that there are two sides are connected to the same point, which does not meet our requirements of the minimum tree, if according to the height of the order, can be very good first to traverse the point, and then to find the smallest Benquan] (

Then it is very simple, the difficulty is in the sort.

#include <iostream> #include <cstdio> #include <queue> #include <algorithm>using namespace std;    const int Wx=2000017;inline int read () {int sum=0,f=1;    Char Ch=getchar (); while (ch< ' 0 ' | |        Ch> ' 9 ') {if (ch== '-') f=-1;    Ch=getchar ();        } while (ch>= ' 0 ' &&ch<= ' 9 ') {sum= (sum<<1) + (sum<<3) +ch-' 0 ';    Ch=getchar (); } return sum*f;} int H[wx];int n,m,num,tot,x,y,z,cnt;int head[wx];int f[wx];long long ans;int vis[wx];struct e{int Nxt,to,dis;}    edge[wx*2];struct node{int l,r,d;        friend BOOL operator < (const node& A,const node& b) {if (H[A.R]==H[B.R]) return A.D < B.D;    return H[A.R] > H[B.R];    }}a[wx];void Add (int from,int to,int dis) {Edge[++num].nxt=head[from];    Edge[num].to=to;    Edge[num].dis=dis; Head[from]=num;}    Queue<int > Q;void BFS (int s) {Q.push (s); vis[1] = 1;        while (!q.empty ()) {int U=q.front (); Q.pop (); for (int i=head[u];i;i=edge[i].NXT) {int v=edge[i].to; a[++ tot].l = u; A[TOT].R = v;            A[TOT].D = Edge[i].dis;                 if (!vis[v]) {vis[v]=1;            Cnt++;q.push (v);    }}}}int find (int x) {if (x==f[x]) return x; Return F[x]=find (F[x]);}    Signed Main () {freopen ("roll.in", "R", stdin);    Freopen ("Roll.out", "w", stdout);    N=read (); M=read ();    for (int i=1;i<=n;i++) h[i]=read ();        for (int j=1;j<=m;j++) {x=read (); Y=read (); Z=read ();        if (H[x]==h[y]) {Add (x, y, z); add (y,x,z);        } else if (H[x]>h[y]) Add (x, y, z);    else Add (y,x,z);    } BFS (1);    for (int i=1;i<=n;i++) f[i]=i;    Sort (a+1,a+1+tot);            for (int i=1;i<=tot;i++) {if (Find (A[I].L)!=find (A[I].R)) {ans+=a[i].d;        F[find (A[I].L)]=find (A[I].R);    }} printf ("%d%lld\n", CNT + 1,ans); return 0;}
T3 Split (split)

Description

Makik roll Dizzy, suddenly split into n only small makik. The little Makik were lined up from left to right, looking very interesting.

You want to flirt with the little Makik, and prepare a game like this: first assign a number to each small makik, and then make multiple inquiries. Each time you ask, specify an interval, for any two small makik within the interval, if they are numbered the same, the small makik on the left is a bad makik. After that, you have to punish all the bad Makik in the range with the right one. If there is no bad makik in the interval, then you will feel a bit bored.

You want to know in advance that you are going to punish the little makik for every inquiry.

Input

The first line of the input file contains a positive integer n, indicating that there are altogether n small Makik.

The next line contains n number a_1, a_2, ..., a_n in turn represent the number each small Makik is assigned to.

The next line gives an integer q, which indicates the number of queries.

The following q line, two integers per line l,r indicates that the range of the inquiry is from the left to the first of the small Makik R only.

Output

Output q line, corresponding to Q-time inquiry. Each query output the most right-most bad Makik ranked in the first place. If there is no bad makik, output "boring".

The problem of violence should be offline, but the problem of the data is really too water, all kinds of violent rolling superscript, eolv with the birthday paradox to us to prove how difficult the problem of the data, but I this spicy chicken did not get to

Thanks to coach education we have to read through the topic, let me this exam found the most water of the third problem, but, because it is too water, make me not as usual look at the data range to do the problem, directly knocked a line tree finished. Originally flattered to think oneself T3 absolute stability, but finally got 20 points.

Suddenly found that\ (a_i\) range is 1e9, this mood ... Shi Shi ... Ruin and ruin ...

This lesson tells us that writing interval operations similar to the data structure of the segment tree must pay attention to the range of input data, because it is easy to remember the precursor to open a bucket, and then the silly explosion of space ... RE ... So be sure to write discretization.

Suddenly found that their discretization is a bit not thorough, review:
Discretization:

    for(int i=1;i<=n;i++){        aa[i]=read();        b[i] = aa[i];    }    sort(b+1,b+1+n);    for(int i = 1; i <= n; ++ i) a[i] = lower_bound(b + 1, b + 1 + n, aa[i]) - b;

Go weight:

    for(int i=1;i<=n;i++)scanf("%d",&a[i]);    int size=unique(a+1,a+1+n)-a-1;    //debug()    //for(int i=1;i<=size;i++)printf("%d ",a[i]);

Look again at this question: for the current range of inquiries, if a position of his predecessor in this interval, then his predecessor's position will have an impact on the answer, so direct discretization, and then record the precursor of each position, and then put the precursor in the line segment tree maintenance. Each time you ask for a direct output interval maximum value.

Code

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define LS (o) o    <<1#define RS (O) o<<1|1using namespace std;const int Wx=2000017;inline int read () {int sum=0,f=1;    Char Ch=getchar (); while (ch< ' 0 ' | |        Ch> ' 9 ') {if (ch== '-') f=-1;    Ch=getchar ();        } while (ch>= ' 0 ' &&ch<= ' 9 ') {sum= (sum<<1) + (sum<<3) +ch-' 0 ';    Ch=getchar (); } return sum*f;}    struct val_tree{int l,r,ma; #define MA (o) t[o].ma}t[wx*4];int pre[wx],a[wx],last[wx],b[wx];int n,m,x,y;void up (int o) {ma (o) =max (MA (LS (o)), MA (RS ( o)));}    void build (int o,int l,int r) {t[o].l=l;t[o].r=r;    if (l==r) {MA (o) =pre[l];return;}    int mid=t[o].l+t[o].r>>1;    if (l<=mid) build (LS (o), l,mid);    if (R>mid) build (RS (o), mid+1,r); Up (o);}    int query (int o,int l,int R) {if (l<=t[o].l&&t[o].r<=r) {return MA (o);    } int mid=t[o].l+t[o].r>>1;    int maxn=0; if (L<=mid) Maxn=max (Maxn,query (LS (o), l,r));    if (r>mid) Maxn=max (Maxn,query (RS (o), l,r)); return MAXN;}    int Aa[wx];int Main () {freopen ("split.in", "R", stdin);    Freopen ("Split.out", "w", stdout);    N=read ();        for (int i=1;i<=n;i++) {aa[i]=read ();    B[i] = Aa[i];    } sort (b+1,b+1+n);    for (int i = 1; I <= n; + + i) a[i] = Lower_bound (b + 1, B + 1 + N, aa[i])-B;        for (int i=1;i<=n;i++) {pre[i]=last[a[i]];    Last[a[i]]=i;    } build (1,1,n);    M=read ();        for (int i=1;i<=m;i++) {x=read (); Y=read ();        int Ans=query (1,x,y);        if (ans<x) printf ("boring\n");    else printf ("%lld\n", ans);    } fclose (stdin);    Fclose (stdout);  return 0;}

10-3 National Day sixth simulation game Puzzle

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.