JOI 2017 Final solution to a problem

T1

Placed on the difference sequence modifications do so modified each modification requires only two positions, and all temperatures each modification will affect later

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define eps 1e-8
int n,m,a[200200];
ll f[200100];
ll s,t,ans;

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

void modify(int pos,ll val)
{
    if (pos>n) return;
    if (f[pos]>0) ans+=s*f[pos];
    else ans+=t*f[pos];
    f[pos]+=val;
    if (f[pos]>0) ans-=s*f[pos];
    else ans-=t*f[pos];
}

signed main()
{
    n=read();m=read();s=read();t=read();
    rep(i,0,n) a[i]=read();
    rep(i,1,n) f[i]=a[i]-a[i-1];
    ans=0;
    rep(i,1,n)
        if (f[i]>0) ans-=s*f[i];
        else ans-=t*f[i];
    while (m--)
    {
        int l=read(),r=read(),x=read();
        modify(l,x);modify(r+1,-x);
        printf("%lld\n",ans);
    }
    return 0;
}

T2

If you find that according to "Express -> quasi-express -> local" car will not order more inferior

For each segment express interval \ ((S_I, S_ {I} +. 1] \) , consider how to find the maximum reachable station

We \ (s_i \) get off there will be a surplus of time, denoted by \ (rst_i \) , the beginning and conclusion of the same way, we hope to establish a quasi-express "a local station can be used to reach the final" at station, so that from \ (s_i \) can get there directly, if proof be considered forward or backward adjustment will not be better

In this case we have \ (O (mk) \) one can consider the establishment of a quasi-point Express, you can use the priority queue greedy

Special attention to some weird sentence

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 998244353
#define int long long
#define eps 1e-8
int n,m,k,now[5050],s[5050];
ll a,b,c,tot,rst[5050];
priority_queue<int> q;
int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

signed main()
{
    n=read();m=read();k=read();
    scanf("%lld%lld%lld%lld",&a,&b,&c,&tot);
    rep(i,1,m) 
    {
        s[i]=read();
        rst[i]=tot-b*(s[i]-1);
        now[i]=s[i];
    }
    int ans=0;
    //rep(i,1,m) cout << now[i] << " ";cout << endl;
    if (b*(s[m]-1)>tot) ans--;
    rep(i,1,m-1)
    {
        if (rst[i]<0) continue;
        int nxt=min(s[i+1],s[i]+rst[i]/a+1);
        ans+=(nxt-s[i]);
        rst[i]-=c*(nxt-s[i]);
        now[i]=nxt;
    }
    rep(i,1,k)
    {
        rep(j,1,m-1)
        {
            if (rst[j]<0) continue;
            int nxt=min(s[j+1],now[j]+rst[j]/a+1);
            q.push(nxt-now[j]);
            rst[j]-=c*(nxt-now[j]);
            now[j]=nxt;
        }
    }
    rep(i,1,k-m)
    {
        if (q.empty()) break;
        ans+=q.top();q.pop();
    }
    printf("%lld",ans);
    return 0;
}

T3

Painting it, then you can find a legitimate program that stepped on the four corners, four cases due to the equivalence we can only deal with the post-rotation matrix stepped lower left corner, and finally take a \ (min \) to

It is clear from the title-half answer implied, but it looks like \ (check \) is not easy

Consider the overall matrix \ (max \) and \ (min \) values for the two points we out \ (MID \) , we consider the lower left corner of the step has \ (\ + min GEQ MID \) , the upper right corner has \ (\ Leq max-MID \) , due to the \ (max \) and \ (min \) will not be in the same ladder in so doing we will be able to take into account the optimal solution, after maintaining a pointer to the right end of the current row (monotone did not fall), to determine what each line in the lower left corner unlawful point is in the upper right corner to

#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
const int N=10000;
const db pi=acos(-1.0);
#define lowbit(x) (x)&(-x)
#define sqr(x) (x)*(x)
#define rep(i,a,b) for (register int i=a;i<=b;i++)
#define per(i,a,b) for (register int i=a;i>=b;i--)
#define fir first
#define sec second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define maxd 2e9
#define eps 1e-8
int n,m,a[2020][2020],ans=maxd,mx=0,mn=maxd;

int read()
{
    int x=0,f=1;char ch=getchar();
    while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
    while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
    return x*f;
}

void reverse1()
{
    rep(i,1,n/2) rep(j,1,m) swap(a[i][j],a[n-i+1][j]);
}

void reverse2()
{
    rep(i,1,n) rep(j,1,m/2) swap(a[i][j],a[i][m-j+1]);
}

bool chk(int mid)
{
    int now=0;
    rep(i,1,n)
    {
        rep(j,1,m)
            if (a[i][j]<mx-mid) now=max(now,j);
        rep(j,1,m)
            if ((a[i][j]>mid+mn) && (j<=now)) return 0;
    }
    return 1;
}

void solve()
{
    int l=0,r=mx-mn,now=0;
    while (l<=r)
    {
        int mid=(l+r)>>1;
        if (chk(mid)) {now=mid;r=mid-1;}
        else l=mid+1;
    }
    ans=min(ans,now);
}

int main()
{
    n=read();m=read();
    rep(i,1,n) rep(j,1,m)
    {
        a[i][j]=read();
        mx=max(a[i][j],mx);
        mn=min(a[i][j],mn);
    }
    solve();
    reverse1();
    solve();
    reverse2();
    solve();
    reverse1();
    solve();
    printf("%d",ans);
    return 0;
}

T4

To be filled pit

Guess you like

Origin www.cnblogs.com/encodetalker/p/11817282.html