8.10 problem solution

T1

This problem turned out to be really greedy, I xxxx, when the exam was originally thought of greed as a result, I wrote a sentence on the code "//贪心不太对的样子,跳近一点多跳几个格子,可能可以给下一个青蛙留出落脚点”,我当时一定是脑子废掉了想那么多,然后这题我就一点头绪都没有了,在看了大概一个多小时什么都没打之后,我把它弃掉之后,在交卷前最后20多分钟随便打了个DP?结果RE0了

It's greedy to talk about it, for you every frog jump as much as possible it can jump the farthest place, after all, if you do not jump the farthest, you will become more than accounted for the stone, to the back of the frog the stone will be left less, about zz I think that greedy wrong idea, let's think about that for each frog for their jumping ability is the same, if a frog can jump the farthest point, happens to be the only point of a frog 2 can be reached, there is only one possible, that is the farthest point of a frog can jump in front of him is the first point, otherwise, as long as 1 between the frog and the farthest point there is a point, 2 frogs can be settled, then the situation will be solved only one stone, then the stone is 1,2 two frogs furthest point, it is life and death They related, and the correctness of our greedy on yy rigorous proof came out, the rest is jumping jump on it, of course, one jump, or will find the farthest point T, so we need a magical $ STL $: $ set $, so we end up Take $ O (nlogn) $ complex This question is the degree to solve

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<set>
 5 #define maxn 1001000
 6 using namespace std;
 7 int t;
 8 int a[maxn];
 9 set <int> ss;
10 int main()
11 {
12     scanf("%d",&t);
13     while(t--)
14     {
15         int n,m,d,l,ans=0;  ss.clear();
16         scanf("%d%d%d%d",&n,&m,&d,&l);
17         a[1]=0;  n++;  ss.insert(0);
18         for(int i=2;i<=n;++i)
19         {
20             scanf("%d",&a[i]);
21             ss.insert(a[i]);
22         }
23         a[++n]=l;  ss.insert(a[n]);
24         while(ss.size()>2)
25         {
26             int bj=0;
27             set<int>::iterator qd=ss.begin();
28             while(*qd<a[n])
29             {
30                 set<int>::iterator ls=--ss.upper_bound(*qd+d);
31                 if(*ls==a[n])  {ans++;  break;}
32                 if(*ls+d>=a[n])  {ss.erase(*ls);  ans++;  break;}
33                 if(*ls<=*qd)  {bj=1;  break;}
34                 qd=ls;  ss.erase(*ls);
35             }
36             if(bj==1)  break;
37             if(ans==m)  break;
38         }
39         if(ans>=m)  printf("Excited\n");
40         else  printf("%d\n",ans);
41     }
42     return 0;
43 }
View Code

T2

Seniors talked about the original question, I waste too, but he kept the tree line of things, I think to be honest examination room, but in fact, emm, how should I say, think of the words actually quite good maintenance, Let me talk about what maintenance

struct the Node {
     int zuo, you; // normal segment tree record jurisdiction 
    int ceng; // zuo to you this interval a total of how many layers 
    LL SUM; // zuo to you how so many layers in a total amount of Jinkela 
    Cut LL; // zuo to you want to delete this interval preceding a total number of layers 
} A [* MAXM . 4 ];

$ Update $ operation when the leaf node achievements normal operation, then that is uploaded to the father when the node information

void Update ( int F) 
{ 
    IF (A [ 2 * F + . 1 ] .cut == 0 ) // the right son of the left son does not delete 
    { 
        A [F] .cut = A [ 2 * F] .cut; 
        A [F ] .ceng = A [ 2 * F] .ceng + A [ 2 * F + . 1 ] .ceng; 
        A [F] .sum = A [ 2 * F] .sum + A [ 2 * F + . 1 ] .sum; 
    } 
    the else  IF (A [ 2 * F + . 1 ] .cut> = A [ 2 * F] .ceng) // the right son of the left son finished deleted
    { 
        A [F] .cut = a [ 2 * F] .cut + a [ 2 * F + . 1 ] .cut-a [ 2 * F] .ceng; // has been partially offset by the right son of the left son cut with 
        a [f] .ceng = A [ 2 * f + 1 ] .ceng; // left son to be deleted over, unable to contribute to 
        A [f] .sum = A [ 2 * f + 1 ] .sum; 
    } 
    the else // delete not Clean son left 
    { 
        a [f] .cut = a [ 2 * f] .cut; // delete the contribution of the right son is clean and clear of 
        a [f] .ceng = a [ 2 * f] .ceng + a [ 2 + F * . 1 ] .ceng-A [ 2+ F * . 1 ] .cut; // left son, the right son is deleted portion 
        A [F] .sum = A [ 2 * F + . 1 ] .sum CAL + ( 2 * F, A [ 2 * F + . 1 ] .cut) ; // function is used to query how much a part of the amount left after his son left his son the right to be deleted 
    } 
}

Then there is the $ update $ function in $ cal $ function, in fact, he kept asking his son through the process to calculate the effect of the deletion on the left and right son caused his son

int CAL ( int F, int W) // the current node is deleted, before deleting the current node and right son, the left son of puncturing not go delete 
{
     // the right son, just enough to delete, return directly to the left son 
    IF (A [ 2 * + F . 1 ] == W .ceng)   return a [F] .sum-a [ 2 * F + . 1 ] .sum;
     // the right son can not be completely deleted, it is ready to delete the right son, the right son of the 
    IF (a [ 2 + F * . 1 ] .ceng> W)   return a [F] .sum-a [ 2 * F + . 1 ] .sum CAL + ( 2 * F + . 1 , W);
     // the right son not delete, delete the remaining tape as well as the right to delete his son left his son, his son left to delete 
    return CAL (2*f,w-a[2*f+1].ceng+a[2*f+1].cut);
}

Explain why not write directly left his son $ sum $, but with the parent - the right to get his son, because his son left his son the right actually need to be removed, but currently your son left and the right not to calculate the contribution deleted his son, also That is $ sum $ value is now left son is not true

The rest is a single point and modify the query

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<stack>
 5 #define maxm 200100
 6 #define ll long long
 7 using namespace std;
 8 struct node{
 9     int zuo,you,ceng;
10     ll sum,cut;
11 }a[maxm*4];
12 int m,q;
13 int cal(int f,int w)
14 {
15     if(a[2*f+1].ceng==w)  return a[f].sum-a[2*f+1].sum;
16     if(a[2*f+1].ceng>w)  return a[f].sum-a[2*f+1].sum+cal(2*f+1,w);
17     return cal(2*f,w-a[2*f+1].ceng+a[2*f+1].cut);
18 }
19 void update(int f)
20 {
21     if(a[2*f+1].cut==0)
22     {
23         a[f].cut=a[2*f].cut;
24         a[f].ceng=a[2*f].ceng+a[2*f+1].ceng;
25         a[f].sum=a[2*f].sum+a[2*f+1].sum;
26     }
27     else if(a[2*f+1].cut>=a[2*f].ceng)
28     {
29         a[f].cut=a[2*f].cut+a[2*f+1].cut-a[2*f].ceng;
30         a[f].ceng=a[2*f+1].ceng;
31         a[f].sum=a[2*f+1].sum;
32     }
33     else
34     {
35         a[f].cut=a[2*f].cut;
36         a[f].ceng=a[2*f].ceng+a[2*f+1].ceng-a[2*f+1].cut;
37         a[f].sum=a[2*f+1].sum+cal(2*f,a[2*f+1].cut);
38     }
39 }
40 void build(int f,int l,int r)
41 {
42     a[f].zuo=l;  a[f].you=r;
43     if(l==r)
44     {
45         int k;  ll v;
46         scanf("%d%lld",&k,&v);
47         if(k==0)  {a[f].sum=v;  a[f].ceng=1;}
48         else  a[f].cut=v;
49         return ;
50     }
51     int mid=(l+r)>>1;
52     build(2*f,l,mid);  build(2*f+1,mid+1,r);
53     update(f);
54 }
55 void change(int f,int d,int opt,ll w)
56 {
57     if(a[f].zuo==a[f].you)
58     {
59         if(opt==0)  {a[f].cut=0;  a[f].sum=w;  a[f].ceng=1;}
60         else  {a[f].sum=0;  a[f].ceng=0;  a[f].cut=w;}
61         return ;
62     }
63     int mid=(a[f].zuo+a[f].you)>>1;
64     if(d<=mid)  change(2*f,d,opt,w);
65     else  change(2*f+1,d,opt,w);
66     update(f);
67 }
68 int main()
69 {
70     scanf("%d%d",&m,&q);
71     build(1,1,m);
72     while(q--)
73     {
74         int c,k;  ll v;  scanf("%d%d%lld",&c,&k,&v);
75         change(1,c,k,v);
76         printf("%lld\n",a[1].sum);
77     }
78     return 0;
79 }
View Code

T3

T3 data over the water, I had been using a 30-point code is water, not understanding positive solution, to leave the pit, but having said that $ getchar $ and $ putchar $ too quickly the point of it, a full card to help me out 3000 mm

Violence will do what he asked, directly simulate it, I probably thought about, complexity should be $ O (qn ^ 2) $ appearance, ran over 11,000

 1 //里层也需要翻
 2 #include<cstdio>
 3 #include<iostream>
 4 #define maxn 2100
 5 using namespace std;
 6 int n,m,q;
 7 char ch;
 8 char hs[maxn],hx[maxn],lz[maxn],ly[maxn];
 9 char a[maxn][maxn];
10 int main()
11 {
12     scanf("%d%d%d",&n,&m,&q);
13     for(int i=1;i<=n;++i)
14         for(int j=1;j<=m;++j)
15         {    
16             ch=getchar();
17             while(ch<'0'||ch>'9')  ch=getchar();
18             while(ch>='0'&&ch<='9')  {a[i][j]=ch;  ch=getchar();}
19         }
20     while(q--)
21     {
22         int x,y,len,i,j;  scanf("%d%d%d",&x,&y,&len);
23         while(len>=1)
24         {
25             for(i=y;i<=y+len-1;++i)  {hs[i]=a[x][i];  hx[i]=a[x+len-1][i];}
26             for(i=x;i<=x+len-1;++i)  {lz[i]=a[i][y];  ly[i]=a[i][y+len-1];}
27             for(i=x,j=y+len-1;i<=x+len-1,j>=y;++i,--j)  a[x][j]=lz[i];
28             for(i=y,j=x;i<=y+len-1,j<=x+len-1;++i,++j)  a[j][y]=hx[i];
29             for(i=x+len-1,j=y;i>=x,j<=y+len-1;--i,++j)  a[x+len-1][j]=ly[i];
30             for(i=y+len-1,j=x+len-1;i>=y,j>=x;--i,--j)  a[j][y+len-1]=hs[i];
31             x++;  y++;  len-=2;
32         }
33     }
34     for(int i=1;i<=n;++i)
35     {
36         for(int j=1;j<=m;++j)  {putchar(a[i][j]);  putchar(' ');}
37         puts("");
38     }
39     return 0;
40 }
Violence optimization miracle

 

Guess you like

Origin www.cnblogs.com/hzjuruo/p/11333123.html
Recommended