hbx cancer of greed series solution to a problem

Greedy thematic cancer hbx series of explanations
A Maximal gcd
  meaning of the questions: now given a positive integer n. You need to find a strictly increasing k positive integers a1, a2, ..., ak, and meet their equal to n and their greatest common factor as large as possible. If not possible, please output -1. \ (1 \ leq n, k
\ leq 10 ^ {10} \)   Solution: After all the factors of n to find out, find the maximum factor x satisfies \ (x * \ frac {k * (k + 1)} {2 } \ leq n \) can. Sequence is \ (1 * x, 2 * x, ..., (k-1) * x, nx * \ frac {k * (k-1)} {2} \)
  Note that the judgment will burst long long!
  Complexity: \ (O (\ sqrt n-) \)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,k,tmp,tp,sum,fac[5005];
int faccnt;
inline bool check(ll x)
{
    return x<=(2*n/k)/(k+1);//!!!
}
int main()
{
    scanf("%lld%lld",&n,&k);
    sum=n;
    if(!check(1))
    {
        puts("-1");
        return 0;
    }
    for(register ll i=1;i*i<=n;++i)
    {
        if(n%i) continue;
        if(check(i)) tmp=max(tmp,i);
        if(check(n/i)) tmp=max(tmp,n/i);
    }
    for(int i=1;i<k;++i)
        printf("%lld ",1ll*i*tmp),sum-=i*tmp;
    printf("%lld\n",sum);
    return 0;
}

  B Arthur and walls
  meaning of the questions: ".", ".", "." Gives a matrix of n * m, which the "*" and two kinds of symbols, the minimum requirement "*" into such blocks Unicom a rectangle. It requires at least need to change a few "*." \ (1 \ leq n, m
\ leq 2000 \)   Solution: If a block of 2 * 2, only a "*" put the "*" change out. bfs can be.
  Complexity: \ (O (^ n-2) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 2005
int G[maxn][maxn],b[5];
char s[maxn][maxn];
int n,m;
struct Node
{
    int x,y;
    Node(){}
    Node(int a,int b):x(a),y(b){} 
};
queue<Node> q;
inline void work(int x,int y)
{
    if(G[x][y])
        G[x][y]=0,q.push(Node(x,y));
}
inline void bfs()
{
    while(!q.empty())
    {
        int x=q.front().x,y=q.front().y;
        q.pop();
        b[1]=b[2]=b[3]=b[4]=0;
        if(x!=1&&y!=1) b[1]=G[x-1][y-1]+G[x-1][y]+G[x][y-1];
        if(x!=1&&y!=m) b[2]=G[x-1][y]+G[x-1][y+1]+G[x][y+1];
        if(x!=n&&y!=1) b[3]=G[x][y-1]+G[x+1][y-1]+G[x+1][y];
        if(x!=n&&y!=m) b[4]=G[x][y+1]+G[x+1][y]+G[x+1][y+1];
        if(b[1]==1)
            work(x-1,y-1),work(x-1,y),work(x,y-1);
        if(b[2]==1)
            work(x-1,y),work(x-1,y+1),work(x,y+1);
        if(b[3]==1)
            work(x,y-1),work(x+1,y-1),work(x+1,y);
        if(b[4]==1)
            work(x,y+1),work(x+1,y),work(x+1,y+1);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;++i)
    {
        scanf("%s",s[i]+1);
        for(int j=1;j<=m;++j)
        {
            if(s[i][j]=='.') q.push(Node(i,j));
            else G[i][j]=1;
        }
    }
    bfs();
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            if(G[i][j]==1) cout<<"*";
            else cout<<".";
        }
        puts(" ");
    }
    return 0;
}

  C Student's Revenge
  meaning of the questions: have a chairman to handle heavy transaction per day, but students are still very disgusted with him. There are n tasks, students will choose a p, in which elected chairman of k to complete the rest of the n-k is not complete.
  The Chairman will complete a task hair white \ (A_ {i} \) , it will not complete the students' dissatisfaction increases \ (b_ {i} \) . President will \ (\ sum {b_ {i }} \) as small as possible, on this basis that the \ (\ sum {a_ {i }} as small as possible \) . But students who want to make the \ (\ sum {a_ {i }} \) as large as possible, on the basis of the \ (\ sum {b_ {i }} \) as large as possible.
  P seeking students choose which one would you choose and the Chairman of the k.
  First output and the output of the students choose not vote for the President of the pk months, and then choose the output chairman of the k. Output in order of numbers.
  \ (1 \ leq k \ leq
p \ leq n \ leq 10 ^ 5,1 \ leq a_ {i}, b_ {i} \ leq 10 ^ 9 \)   Solution: If p given task, bound to the Chairman press b then a descending sort in ascending order resolved. So the anti-push press b then ascending certainly not before the election on a pk a descending order. Therefore, prior to first remove a pk of the n (mark can not selected).
  Secondly, we want to choose a maximum of k and pk b-largest. To make up for that only the President of the k, there must be the first k b b values are greater than the value of the back of a pk.Look concrete realization of the code.
  Complexity: \ (O (n-\ log n-) \)

#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100005
struct Things
{
    int a,b,id,state;
}thi[maxn];
int n,p,k,vis[maxn],cnt,num;
inline bool cmp1(Things x1,Things x2)
{
    if(x1.b!=x2.b) return x1.b<x2.b;
    if(x1.a!=x2.a) return x1.a>x2.a;
    return x1.state<x2.state;
}
inline bool cmp2(Things x1,Things x2)
{
    if(x1.a!=x2.a) return x1.a>x2.a;
    return x1.b>x2.b;
}
int main()
{
    scanf("%d%d%d",&n,&p,&k);
    for(int i=1;i<=n;++i)
        scanf("%d%d",&thi[i].a,&thi[i].b),thi[i].id=i;
    sort(thi+1,thi+n+1,cmp1);
    for(int i=1;i<=p-k;++i) thi[i].state=1;//扔后面去
    sort(thi+1,thi+n+1,cmp2);
    for(int i=1;cnt<k;++i)
        if(!thi[i].state)
        {
            ++cnt;
            vis[thi[i].id]=1;
            thi[i].state=2;//同上
            printf("%d ",thi[i].id);
        }
    sort(thi+1,thi+n+1,cmp1);
    cnt=0;
    for(int i=n;num<p-k;--i)//从后往前扫
    {
        if(cnt>=k)
        {
            ++num;
            printf("%d ",thi[i].id);
        }
        if(vis[thi[i].id]) ++cnt;
    }
    return 0;
}

  D Ball coloring
  meaning of problems: there are n number to be the number of the two numbers are put on the stack and l r stack. Seeking \ (min ((R_ {min {max}} -R_) * (L_ {min {max}} -L_)) \)
  \ (. 1 \ n-Leq \ Leq 200000,1 \ Leq NUM \ ^ 10. 9 Leq \)
  question solution: Let \ (Min, Max \) is a global maximum (minimum) value.
  1): If Min, Max is not the same heap: all thrown into a smaller number of Min heap, thrown into a large number of Max heap.
  2): If the stack in the same: we demand a \ (min (R_ {min {max}} -R_) \) . Let x number of small value, y number of large value. Sort by x. Followed by exchange of x, y and update the answer.
  Note: If Min, Max may be the same number of skipped 2).
  Complexity: \ (O (n-\ log n-) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
struct Card
{
    int x,y;
    inline friend bool operator < (Card a,Card b)
        {
            if(a.x==b.x) return a.y<b.y;
            return a.x<b.x;
        }
}card[maxn];
int Rmax,Rmin,Bmax,Bmin,maxpos,minpos;
int main()
{
    int n;
    scanf("%d",&n);
    if(n==1)
    {
        puts("0");
        return 0;
    }
    for(int i=1;i<=n;++i)
    {
        scanf("%d%d",&card[i].x,&card[i].y);
        if(card[i].x>card[i].y) swap(card[i].x,card[i].y);
    }
    sort(card+1,card+n+1);
    int maxy=card[1].y,minx=card[1].x;
    for(int i=1;i<=n;++i)
    {
        if(card[i].x<=minx&&card[i].y>=maxy)
        {
            maxpos=minpos=i;
            minx=card[i].x,maxy=card[i].y;
        }
        else if(card[i].x<minx)
        {
            minpos=i;
            minx=card[i].x;
        }
        else if(card[i].y>maxy)
        {
            maxpos=i;
            maxy=card[i].y;
        }
    }
    Rmax=maxy,Bmin=minx;//全局最大最小
    Rmin=card[minpos].y,Bmax=card[maxpos].x;
    for(int i=1;i<=n;++i)
    {
        Rmin=min(Rmin,card[i].y);
        Bmax=max(Bmax,card[i].x);
    }
    long long ans=1ll*(Rmax-Rmin)*(Bmax-Bmin);//第一种情况
    if(maxpos!=minpos)//第二种情况
    {
        Bmax=maxy,Bmin=minx;
        Rmax=max(card[n].x,card[1].y);
        int premin=card[1].y;
        Rmin=min(card[1].y,card[2].x);
        int tmp=Rmax-Rmin;
        for(int i=2;i<n;++i)
        {
            Rmax=max(card[i].y,Rmax);
            Rmin=min(min(card[i].y,premin),card[i+1].x);
            premin=min(premin,card[i].y);
            if(Rmax-Rmin<tmp) tmp=Rmax-Rmin;
        }
        ans=min(ans,1ll*tmp*(Bmax-Bmin));
    }
    printf("%lld\n",ans);
    return 0;
}

  E Ant man
  title meaning: with n points, each point has x, a, b, c, d five properties. A defined distance from i to j is
  \ Cases the begin {}
\ {i} -x_ MID X_ {j} \ + MID B_ C_ {i} + {j}, & X_ {i}> {j} X_ \ NEWLINE
\ X_ {I} -x_ MID {J} \ + MID + D_ {I} A_ {J}, & X_ {J}> {I} X_
\ Cases} End {
  given start and end points, each point exactly once after seek shortest.
  \ (n \ leq 5000,1 \ leq
x, a, b, c, d \ leq 10 ^ 9 \)   guarantee x, a, b, c, d are strictly monotonically increasing.
  Solution: insert directly in the interval, to maintain a linked list.
  Complexity: \ (O (^ n-2) \)

#include<bits/stdc++.h>
using namespace std;
struct Point
{
    long long x,a,b,c,d;
}poi[5005];
int n,s,e,nex[5005],tmppos;
long long ans,cost,tmpcost;
inline long long dist(int x,int y)
{
    Point a=poi[x],b=poi[y];
    if(b.x<a.x) return a.x-b.x+a.c+b.b;
    return b.x-a.x+a.d+b.a; 
}
int main()
{
    scanf("%d%d%d",&n,&s,&e);
    for(int i=1;i<=n;++i) scanf("%lld",&poi[i].x);
    for(int i=1;i<=n;++i) scanf("%lld",&poi[i].a);
    for(int i=1;i<=n;++i) scanf("%lld",&poi[i].b);
    for(int i=1;i<=n;++i) scanf("%lld",&poi[i].c);
    for(int i=1;i<=n;++i) scanf("%lld",&poi[i].d);
    nex[s]=e;
    ans+=dist(s,e);
    for(int i=1;i<=n;++i)
    {
        if(i==s||i==e) continue;
        cost=1e18;
        for(int j=s;j!=e;j=nex[j])
        {
            tmpcost=dist(j,i)+dist(i,nex[j])-dist(j,nex[j]);
            if(cost>tmpcost)
            {
                cost=tmpcost;
                tmppos=j;
            }
        }
        ans+=cost;
        nex[i]=nex[tmppos];
        nex[tmppos]=i;
    }
    printf("%lld\n",ans);
    return 0;
}

The above is exam questions.


  F New Year Snowman
  meaning of the questions: given \ (R_ {I} \) , seeking mutually different elements up to how many triples. \ (1 \ leq n \ leq
5 * 10 ^ 5, r_ {i} \ leq 10 ^ 6 \)   Solution: each to the remaining three to come up.
  Complexity: \ (O (n-\ log n-) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005
int n,cnt,tmp[maxn],anscnt,t1,t2,t3;
struct Ball
{
    int size,num;
    inline friend bool operator < (Ball a,Ball b)
        {
            if(a.num==b.num) return a.size<b.size;
            return a.num<b.num;
        }
}ball[maxn],tmpa,tmpb,tmpc;
struct Ans
{
    int t1,t2,t3;
}ans[maxn];
priority_queue<Ball> q;
inline void func(Ball x)
{
    if(x.num>1) q.push((Ball){x.size,--x.num});
    else --cnt;
}
inline void work()
{
    tmpa=q.top(),q.pop();
    tmpb=q.top(),q.pop();
    tmpc=q.top(),q.pop();
    t1=tmpa.size,t2=tmpb.size,t3=tmpc.size;
    if(t1<t2) swap(t1,t2);
    if(t1<t3) swap(t1,t3);
    if(t2<t3) swap(t2,t3);
    ans[++anscnt]=(Ans){t1,t2,t3};
    func(tmpa),func(tmpb),func(tmpc);
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
        scanf("%d",&tmp[i]);
    sort(tmp+1,tmp+n+1);
    for(int i=1;i<=n;++i)
    {
        if(tmp[i]!=tmp[i-1])
            ball[++cnt].size=tmp[i],ball[cnt].num=1;
        else ++ball[cnt].num;
    }
    for(int i=1;i<=cnt;++i) q.push(ball[i]);
    while(cnt>=3)
        work();
    printf("%d\n",anscnt);
    for(int i=1;i<=anscnt;++i)
        printf("%d %d %d\n",ans[i].t1,ans[i].t2,ans[i].t3);
    return 0;
}

  G South Park Montreal stack light floc
  that Italy: For positive integer sequence \ (a_ {i} \) and (B_ {I} \) \ , and b sequences are not strictly monotonic increasing, so that \ (max (\ mid a_ { i} -b_ {i} \ mid ) \) as small as possible. Given \ (A_ {I} \) .
\ (n \ leq 5 * 10
^ 6 \)   Solution: a draw \ (a_ {i} \) line graph answer can be found as the difference of the maximum reverse addition of the two rounded up. Of course, half can (although I do not know why run with a log than the log also did not bring faster).
  Complexity: \ (O (n-) \)

#include<bits/stdc++.h>
using namespace std;
long long a[5000005],sa,sb,sc,sd,mod;
int n;
inline long long mul(long long a,long long b)
{
    return a*b%mod;
}
inline long long func(long long x)
{
    return (mul(sa,mul(x,mul(x,x)))+mul(sb,mul(x,x))+mul(sc,x)+sd)%mod;
}
inline void pre()//生成数据的
{
    scanf("%d%lld%lld%lld%lld%lld%lld",&n,&sa,&sb,&sc,&sd,&a[1],&mod);
    for(int i=2;i<=n;++i)
        a[i]=(func(a[i-1])+func(a[i-2]))%mod;
}
int main()
{
    pre();
    long long ans=-1e18,maxn=-1e18;
    for(int i=1;i<=n;++i)
    {
        if(maxn>a[i]) ans=max(ans,(maxn-a[i]+1)>>1);
        else maxn=a[i];
    }
    printf("%lld\n",ans);
    return 0;
}

  H Pavel and Triangles
  that Italy: there are n stick, the length of the i \ (^ {i-2}. 1 \) . A given number of each stick \ (A_ {I} \) , find the maximum number of triangles can be composed.
  \ (1 \ leq n \ leq
3 * 10 ^ 5, a_ {i} \ leq 10 ^ 9 \)   Solution: front to back sweep, isosceles priority groups, there are more groups to equilateral.
  Complexity: \ (O (n-) \)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[300005];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%lld",&a[i]);
    ll ans=a[1]/3,num;
    a[1]%=3;
    ll res=a[1];
    for(int i=2;i<=n;++i)
    {
        num=min(res,a[i]/2);
        res-=num;
        ans+=num;
        a[i]-=num*2;
        ans+=a[i]/3;
        res+=a[i]%3;
    }
    printf("%lld",ans);
    return 0;
}

  I Nauuo and Cards
  meaning of the questions: Do you have got n cards, the deck of n cards, there are n 0 Zhang cards, and n number cards (from 1 to n). One operation is defined as the bottom of his cards into the deck and the top deck of cards to get hands, requires the use of a minimum number of operations that can make the deck of cards becomes \ (1 \ sim n \) of ordered sequence.
  Solution: If a number plate in hand, directly received the first one to call. Each card position \ (POS_ {I} \) , consideration of \ ((POS [I] + 1'd) + (Ni) \) , i.e. to fold increase played cards. Can take max. If a license plate in the pile, to see whether it is formed from the \ (POS [. 1] \ n-SIM \) , \ (. 1 \ SIM K \) sequences. If such a sequence is clearly better.
  Complexity: \ (O (n-) \)

#include<cstdio>
using namespace std;
#define maxn 200005
int a[maxn], b[maxn], pos[maxn], ans;
inline int max(int a, int b)
{
    return a > b ? a : b;
}
int main()
{
    int n, i;
    scanf("%d", &n);
    for (i = 1; i <= n; ++i) scanf("%d", &a[i]), pos[a[i]] = 0;
    for (i = 1; i <= n; ++i) scanf("%d", &b[i]), pos[b[i]] = i;
    for (i = 1; i <= n; ++i) ans = max(ans, pos[i] - i + n + 1);
    if (pos[1])
    {
        for (i = 2; pos[i] == pos[1] + i - 1; ++i);
        if (pos[i - 1] == n)
        {
            int j;
            for (j = i; j <= n && pos[j] <= j - i; ++j);
            if (j > n)
            {
                printf("%d\n", n + 1 - i);
                return 0;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

  J Match Points
  that Italy: the given number of columns \ (X_ {I} \) , if the \ (Z \ Leq \ {I} -x_ MID X_ {J} \ MID \) , called \ (x_ {i}, x_ {j} \) can be matched.
  Seeking paired up to how many groups. \ (2 \ leq n \ leq
2 * 10 ^ 5,1 \ leq z, x_ {i} \ leq10 ^ 9 \)   Solution: two minutes. A mid front and rear mid sequentially matched to one.
  Complexity: \ (O (n-\ log n-) \)

#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
int n,z,pos[maxn];
inline bool check(int x)
{
    for(int i=1;i<=x;++i)
        if(abs(pos[i]-pos[n-x+i])<z) return false;
    return true;
}
int main()
{
    scanf("%d%d",&n,&z);
    for(int i=1;i<=n;++i) scanf("%d",&pos[i]);
    sort(pos+1,pos+n+1);
    int l=0,r=(n>>1),mid,ans;
    while(l<=r)
    {
        mid=(l+r)>>1;
        if(check(mid)) l=mid+1,ans=mid;
        else r=mid-1;
    }
    printf("%d\n",ans);
    return 0;
}

  K Artem and Array
  meaning of the questions: given sequence \ (A_ {I} \) , each of a number by deleting a number of left and right side can be obtained a minimum number of points. Seeking fraction of the maximum. \ (1 \ leq n \ leq
5 * 10 ^ 5,1 \ leq a_ {i} \ leq 10 ^ 6 \)   Solution: deleting large first intermediate small sides (monotone stack), in addition to sorting by deleting the last two outside.
  Complexity: \ (O (n-\ log n-) \)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[600005], ans;
int n, top, x;
int main()
{
    scanf("%d", &n);
    while (n--)
    {
        scanf("%d", &x);
        while (top && a[top] <= x && a[top] <= a[top - 1])
            ans += min(a[--top], x * 1ll);
        a[++top] = x;
    }
    sort(a + 1, a + top + 1);
    for (int i = 1; i <= top - 2; ++i) ans += a[i];
    printf("%lld", ans);
    return 0;
}

  L Beijing Guards
  that Italy: n individual form a ring. Each person received gifts and he can not have people on both sides are the same. Q. How many gifts you need most. Everyone needs \ (a_ {i} \) a gift. \ (1 \ leq n \ leq
10 ^ 5 \)   Solution: If n is even taken directly \ (max (a_ {i} + a_ {i + 1}) \) can. Otherwise half. Set \ (a_ {1} \) is about the dividing line. If i is odd then try to take the left or right to take. Finally, look at the n-th whether to take over on the left.
  Note that n = 1 to the direct output.
  Complexity: \ (O (n-\ log n-) \)

#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100005
int n, a[maxn], cl[maxn], cr[maxn];
long long l, r;
inline bool check(long long x)
{
    cl[1] = a[1];
    for (int i = 2; i <= n; ++i)
    {
        if (i & 1)
        {
            cr[i] = min(0ll + a[i], x - a[1] - cr[i - 1]);
            cl[i] = a[i] - cr[i];
        }
        else
        {
            cl[i] = min(a[i], a[1] - cl[i - 1]);
            cr[i] = a[i] - cl[i];
        }
    }
    return !cl[n];
}
int main()
{
    while (scanf("%d", &n) && n)
    {
        l = r = 0;
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), r += a[i];
        if (n == 1)
        {
            printf("%d\n", a[1]);
            continue;
        }
        a[n + 1] = a[1];
        for (int i = 1; i <= n; ++i) l = max(l, 0ll + a[i] + a[i + 1]);
        if (!(n & 1))
        {
            printf("%lld\n", l);
            continue;
        }
        while (l <= r)
        {
            long long mid = (l + r) >> 1;
            if (check(mid)) r = mid - 1;
            else l = mid + 1;
        }
        printf("%lld\n", l);
    }
    return 0;
}

  M Moving Tables
  meaning of the questions: There is a corridor, you can only through a table. Move the table between any two rooms to be 10 minutes. Given n the table and starting and ending points, to seek a maximum number of minutes to move those. The same time can move more than one table. Room 400, \ (n-\ Leq 200 is \)
  Solution: The moving section 10 and then added to the final take max.
  Complexity: \ (O (^ n-2) \)

#include<bits/stdc++.h>
using namespace std;
int cnt[405];
int main()
{
    int t, n, st, ed, ans;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &n);
        memset(cnt, 0, sizeof(cnt));
        while (n--)
        {
            scanf("%d%d", &st, &ed);
            if (st > ed) swap(st, ed);
            if (!(st & 1)) --st;
            if (ed & 1) ++ed;
            for (int i = st; i <= ed; ++i) cnt[i] += 10;
        }
        ans = 0;
        for (int i = 1; i <= 400; ++i) ans = max(ans, cnt[i]);
        printf("%d\n", ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/123789456ye/p/11517487.html