Comet OJ - Contest # 14 problem solution

The nature Contest14: interval coverage + Tarjan (

A

To both sides of the square distance formula

Note To long long

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
using namespace std;

int x[100001];
int y[100001];
int n,i,j,k,l,X,Y,R,ans;

int main()
{
//  freopen("a.in","r",stdin);
    
    scanf("%d%d%d%d",&n,&X,&Y,&R);
    fo(i,1,n)
    scanf("%d%d",&x[i],&y[i]);
    
    fo(i,1,n)
    if (((long long)(x[i]-X)*(x[i]-X)+(long long)(y[i]-Y)*(y[i]-Y))<=(long long)R*R)
    ++ans;
    
    printf("%d\n",ans);
}

B

Obviously p and k is the position of the two most aside

Consider the position i and n (left / right / left)

code

Compare ugly

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
using namespace std;

char a[1000001];
int T,n,i,j,k,l,ans,s1,s2,s3,s4;
char ch;

int main()
{
//  freopen("b.in","r",stdin);
    
    scanf("%d",&T);
    for (;T;--T)
    {
        ans=-1;
        scanf("%d",&n);
        
        fo(i,1,n)
        {
            ch=getchar();
            while (ch<'a' || ch>'z')
            ch=getchar();
            
            a[i]=ch;
        }
        
        fo(i,1,n)
        if (a[i]=='p')
        break;
        
        fd(j,n,1)
        if (a[j]=='k')
        break;
        
        fo(k,i+1,n)
        if (a[k]=='i')
        break;
        
        fo(l,k+1,n)
        if (a[l]=='n')
        break;
        if (i>=1 && i<k && k<l && l<j && j<=n && a[i]=='p' && a[k]=='i' && a[l]=='n' && a[j]=='k')
        ans=max(ans,max(max(k-i-1,l-k-1),j-l-1));
        
        fd(l,j-1,k+1)
        if (a[l]=='n')
        break;
        if (i>=1 && i<k && k<l && l<j && j<=n && a[i]=='p' && a[k]=='i' && a[l]=='n' && a[j]=='k')
        ans=max(ans,max(max(k-i-1,l-k-1),j-l-1));
        
        fd(l,j-1,1)
        if (a[l]=='n')
        break;
        fd(k,l-1,i+1)
        if (a[k]=='i')
        break;
        if (i>=1 && i<k && k<l && l<j && j<=n && a[i]=='p' && a[k]=='i' && a[l]=='n' && a[j]=='k')
        ans=max(ans,max(max(k-i-1,l-k-1),j-l-1));
        
        printf("%d\n",ans);
    }
}

C

* 1 interval coverage

I started to think that one pair intervals can only be considered once the answer

Maintenance breakpoint, then a solution of breakpoints = 1 (plus inclusive)

After primary coating, an outer constant interval, becomes zero in the interval, the boundary becomes 1

Together can be maintained outside the interval 2 *, constant in the interval, the boundaries + 2 ^ (i-1)

The answer i is the total number of breakpoints -2 ^ i

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mod 20050321
using namespace std;

long long p[2001];
int L[2001];
int R[2001];
bool b[2001];
long long sum[2001];
long long Sum[2001];
int n,m,i,j,k,l;
long long ans;

int main()
{
//  freopen("c.in","r",stdin);
    
    scanf("%d%d",&n,&m);
    p[0]=1;
    fo(i,1,m)
    {
        scanf("%d%d",&L[i],&R[i]);
        p[i]=p[i-1]*2%mod;
    }
    
    sum[0]=sum[n]=1;
    fo(i,1,m)
    {
        fo(j,0,n) Sum[j]=sum[j];
        fo(j,0,L[i]-2) Sum[j]=(Sum[j]+sum[j])%mod;
        fo(j,R[i]+1,n) Sum[j]=(Sum[j]+sum[j])%mod;
        Sum[L[i]-1]=(Sum[L[i]-1]+p[i-1])%mod;
        Sum[R[i]]=(Sum[R[i]]+p[i-1])%mod;
        
        ans=0;
        fo(j,0,n)
        sum[j]=Sum[j],Sum[j]=0,ans=(ans+sum[j])%mod;
        
        printf("%lld\n",(ans-p[i]+mod)%mod);
    }
}

D

* 2 interval coverage

Routine asks if the result of the operation to put some sort interrogation offline r, each time adding a calculated operating answer

To maintain each of the two end sections (left and right parentheses), then add a section for each additional maximum of four brackets, each of the brackets will only be deleted once

Each plus an interval, equivalent to an intermediate endpoint deleted (overwritten large energy is small), then both sides plus a new endpoint

Each inquiry is seeking to modify the number of remaining weight suffix * and

With set maintenance brackets, each time to find the middle of the interval after disconnection, maintaining your answer Fenwick tree

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <set>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define low(x) (x&-(x))
using namespace std;

struct qs{
    int l,r,id;
} q[500001];
struct type{
    int x,s,t; //0=right 1=left
    bool friend operator < (type a,type b) {return a.x<b.x || a.x==b.x && a.t<b.t;}
};
int a[500001][3];
long long ans[500001];
long long tr[500001];
multiset<type> st;
multiset<type> :: iterator I,J;
int n,m,Q,i,j,k,l;

bool cmp(qs a,qs b)
{
    return a.r<b.r;
}

void change(int t,long long s)
{
    while (t<=n)
    {
        tr[t]+=s;
        t+=low(t);
    }
}
long long find(int t)
{
    long long ans=0;
    
    while (t)
    {
        ans+=tr[t];
        t-=low(t);
    }
    
    return ans;
}

int main()
{
//  freopen("d.in","r",stdin);
    
    scanf("%d%d%d",&n,&m,&Q);
    fo(i,1,n)
    scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);
    fo(i,1,Q)
    scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
    
    sort(q+1,q+Q+1,cmp);
    
    st.insert({0,0,1});
    st.insert({m,0,0});
    fo(i,1,Q)
    {
        fo(j,q[i-1].r+1,q[i].r)
        {
            I=st.lower_bound({a[j][0]-1,0,1});
            if (I!=st.begin())
            {
                --I;
                if ((*I).x<a[j][0]-1)
                {
                    k=(*I).s;
                    st.insert({a[j][0]-1,k,0});
                    st.insert({a[j][0]-1,k,1});
                }
            }
            
            I=st.upper_bound({a[j][1],0,0});
            if (I!=st.end())
            {
                if (a[j][1]<(*I).x)
                {
                    k=(*I).s;
                    st.insert({a[j][1],k,0});
                    st.insert({a[j][1],k,1});
                }
            }
            
            I=st.lower_bound({a[j][0]-1,0,1});
            J=st.upper_bound({(*I).x,0,1});
            while (I!=st.end() && (*I).x<a[j][1])
            {
                if ((*I).s)
                change((*I).s,-(long long)a[(*I).s][2]*((*J).x-(*I).x));
                
                st.erase(I);
                J=st.lower_bound({a[j][0]-1,0,1});
                st.erase(J);
                
                I=st.lower_bound({a[j][0]-1,0,1});
                J=st.upper_bound({(*I).x,0,1});
            }
            
            st.insert({a[j][0]-1,j,1});
            st.insert({a[j][1],j,0});
            change(j,(long long)a[j][2]*(a[j][1]-a[j][0]+1));
        }
        
        ans[q[i].id]=find(q[i].r)-find(q[i].l-1);
    }
    
    fo(i,1,Q)
    printf("%lld\n",ans[i]);
}

E

Tarjan*1

This should be in addition to the simple number theory that road most of the water E

Tarjan Unicom strong reduction component, maintaining a minimum DP right side from the origin to each point, the right side of the maximum, the maximum difference

Correctness: The maximum difference between the maximum & the minimum path-related, then it must be another computing to find the back of the (big or small or) time

Attention to detail, consider the extreme values ​​location (home, edge, new point)

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
using namespace std;

int a[500001][3];
int ls[200001];
int A[500001][3];
int Ls[200001];
int dfn[200001];
int low[200001];
int d[200001];
int D[200001];
int mx[200001];
int mn[200001];
bool bz[200001];
int num[200001];
int f[200001][3]; //mn,mx,ans
int n,m,Q,i,j,k,l,len,Len,tot,h,t;

void New(int x,int y,int z)
{
    ++len;
    a[len][0]=y;
    a[len][1]=ls[x];
    ls[x]=len;
    a[len][2]=z;
}
void NEW(int x,int y,int z)
{
    ++Len;
    A[Len][0]=y;
    A[Len][1]=Ls[x];
    Ls[x]=Len;
    A[Len][2]=z;
    
    ++D[y];
}

void dfs(int t)
{
    int i;
    
    ++j;
    dfn[t]=j;
    low[t]=j;
    bz[t]=1;
    d[++l]=t;
    
    for (i=ls[t]; i; i=a[i][1])
    {
        if (!dfn[a[i][0]])
        {
            dfs(a[i][0]);
            low[t]=min(low[t],low[a[i][0]]);
        }
        else
        if (bz[a[i][0]])
        low[t]=min(low[t],dfn[a[i][0]]);
    }
    
    if (dfn[t]==low[t])
    {
        ++tot;
        while (d[l]!=t)
        {
            bz[d[l]]=0;
            num[d[l--]]=tot;
        }
        bz[d[l]]=0;
        num[d[l--]]=tot;
    }
}

int main()
{
//  freopen("e.in","r",stdin);
//  freopen("b.out","w",stdout);
    
    scanf("%d%d%d",&n,&m,&Q);
    fo(i,1,m)
    {
        scanf("%d%d%d",&j,&k,&l);
        New(j,k,l);
    }
    
    memset(mx,190,sizeof(mx));
    memset(mn,60,sizeof(mn));
    j=l=0;
    dfs(1);
    
    fo(j,1,n)
    if (num[j])
    {
        for (i=ls[j]; i; i=a[i][1])
        if (num[a[i][0]])
        {
            if (num[j]==num[a[i][0]])
            {
                mx[num[j]]=max(mx[num[j]],a[i][2]);
                mn[num[j]]=min(mn[num[j]],a[i][2]);
            }
            else
            NEW(num[j],num[a[i][0]],a[i][2]);
        }
    }
    
    h=t=0;
    fo(i,1,tot)
    if (!D[i])
    d[++t]=i;
    
    fo(i,1,tot)
    {
        f[i][0]=mn[i];
        f[i][1]=mx[i];
        f[i][2]=f[i][1]-f[i][0];
    }
    while (h<t)
    {
        for (i=Ls[d[++h]]; i; i=A[i][1])
        {
            f[A[i][0]][0]=min(f[A[i][0]][0],min(f[d[h]][0],A[i][2]));
            f[A[i][0]][1]=max(f[A[i][0]][1],max(f[d[h]][1],A[i][2]));
            
            f[A[i][0]][2]=max(f[A[i][0]][2],A[i][2]-f[d[h]][0]);
            f[A[i][0]][2]=max(f[A[i][0]][2],mx[A[i][0]]-f[d[h]][0]);
            f[A[i][0]][2]=max(f[A[i][0]][2],mx[A[i][0]]-A[i][2]);
            
            f[A[i][0]][2]=max(f[A[i][0]][2],f[d[h]][1]-A[i][2]);
            f[A[i][0]][2]=max(f[A[i][0]][2],f[d[h]][1]-mn[A[i][0]]);
            f[A[i][0]][2]=max(f[A[i][0]][2],A[i][2]-mn[A[i][0]]);
            
            f[A[i][0]][2]=max(f[A[i][0]][2],max(f[d[h]][2],0));
            
            --D[A[i][0]];
            if (!D[A[i][0]])
            d[++t]=A[i][0];
        }
    }
    
    for (;Q;--Q)
    {
        scanf("%d",&j);
        if (num[j] && f[num[j]][2]>=0)
        printf("%d\n",f[num[j]][2]);
        else
        printf("-1\n");
    }
}

F

Tarjan*2

Obviously you can find fellowship and then find point cut, optimize and even side with the Chairman of the tree

Hu mouth about

Press horizontal / vertical line sequential scanning, consider the line segment intersects a and b

Even when a to a, b in the leaves look upon accession by the interval b is connected to the interrogator

Each section is connected to the side of his son, when asked on the original side of the leaf nodes even when the new leaf node, if it is not even delete some segments

Or a modified query operation node and the number of edges connected level log n

After both orders finished out Tarjan seeking to cut points

code

I did not write

Guess you like

Origin www.cnblogs.com/gmh77/p/11827296.html