ASC 20簡要題解

題目鏈接
A:暴力kmp,dp計算答案,一個串是循環串當且僅當i%(i-f[i])==0,此時(i-f[i])爲最小循環節
B:模擬,注意第二種規則是說,“括號的方向朝着箭頭指向的方向”,把“(“當成+1,”)“當成-1,找到前綴和最小的地方,從那裏將循環切斷即可得到一個必然合法的括號序列
C:樹哈希。由於這裏數據範圍比較小,可以直接用set記錄每個節點所有兒子的id.可以看出,兩個節點不同意味着要麼顏色不同,要麼存在兒子不同。因此可以在搞一個map<pair<int,set>,int> 來存所有不同的節點,可以看出比較一次的複雜度是O(sizeof(set)) .後面的做法就有很多了,我的方法比較暴力,首先二分答案,然後直接給每個節點一個隨幾的顏色,dfs的時候,當碰到有相同id的兒子出現時,修改其中一個兒子。修改的方法是暴力去找這棵子樹中是否存在一個節點,使得修改這個點的顏色後不會和其他節點產生衝突,如果找不到就返回false ;
代碼雖然能過數據,然而有地方寫錯了,如果有讀者發現還請指正。
D:pqdp
E:可以證明,如果可以合併出來,那麼必然可以貪心的按照任意順序合併出來,因此暴力合併即可
F:dp[i][j]代表分別以i和j作爲起點所能產生的最長的平行的街道長度,顯然轉移的時候可以將i連出去的邊和j連出去的邊排序之後雙指針搞,複雜度就是O(nm)
G:可以看出,長度超過20的部分都沒用,因此可以記錄s[i][j]代表第i個字母做2^j之後產生的字符串,快速冪那樣寫寫就好了
H:暴力splay模擬
I:二分答案後,可以看出咖啡館能修在0.5處就修在0.5處,因此只要求一個最大匹配,最少需要的咖啡館就是總點數-最大匹配,與p比較一下大小即可
J:編譯原理式的模擬,還沒有補過

A:

#include<bits/stdc++.h>
using namespace std;
const int Inf=1e9;
char s[5050];
int f[5050];
int dp[5050];
int pre[5050],mul[5050],len[5050];
int ls;
void kmp(char *s)
{
    f[0]=f[1]=0;
    for(int i=1;s[i];i++)
    {
        int j=f[i];
        while(j&&s[i]!=s[j])j=f[j];
        f[i+1]=s[i]==s[j]?j+1:0;
    }
}
int main()
{
    freopen("decomp.in","r",stdin);
    freopen("decomp.out","w",stdout);
    scanf("%s",s+1);
    ls=strlen(s+1);
    for(int i=1;i<=ls;i++)dp[i]=Inf;
    dp[0]=0;
    for(int i=0;i<ls;i++)
    {
        kmp(s+i+1);
        for(int j=1;j<=ls-i;j++)
        {
            if(j%(j-f[j])==0)
            {
                if(dp[i+j]>dp[i]+j-f[j])
                {
                    dp[i+j]=dp[i]+j-f[j];
                    pre[i+j]=i;
                    len[i+j]=(j-f[j]);
                    mul[i+j]=j/(j-f[j]);
                }
            }
        }
    }
    vector<string>V1;
    vector<int>V2;
    for(int now=ls;now;now=pre[now])
    {
        V2.push_back(mul[now]);
        string tp;
        for(int i=pre[now]+1;i<=pre[now]+len[now];i++)tp.push_back(s[i]);
        V1.push_back(tp);
    }
    reverse(V1.begin(),V1.end());
    reverse(V2.begin(),V2.end());
    printf("%d\n",dp[ls]);
    for(int i=0;i<V1.size();i++)
    {
        cout<<V1[i]<<" "<<V2[i]<<endl;
    }
}

B:

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>pi;
const int Maxn=400020,Maxe=400020;
typedef pair<int,int>pi;
int n;
vector<int>G[Maxn];
int id[Maxn];//A->B
int ne;
int done[Maxn];
int rev[Maxn];
int eu[Maxe],ev[Maxe],ety[Maxe],w[Maxe],ans[Maxe];
void add(int u,int v,int ty)
{
    eu[ne]=u,ev[ne]=v,ety[ne]=ty;
    w[ne]=0;
    G[u].push_back(ne++);
    eu[ne]=v,ev[ne]=u,ety[ne]=ty;
    w[ne]=1;
    G[v].push_back(ne++);
}
void solve(int st)
{
    //printf("st=%d\n",st);
    vector<int>V;
    V.push_back(G[st][0]);
    int x=ev[G[st][0]],last=G[st][0];
    int rep[2];
    rep[0]=rep[1]=0;
    rep[w[G[st][0]]]++;
    for(;x!=st;)
    {
        //printf("x=%d\n",x);
        if(G[x][0]!=(last^1))
        {
            V.push_back(G[x][0]);
            last=G[x][0];
            rep[w[G[x][0]]]++;
            x=ev[G[x][0]];
        }
        else
        {

            V.push_back(G[x][1]);
            last=G[x][1];
            rep[w[G[x][1]]]++;
            x=ev[G[x][1]];
        }
    }
    for(int i=0;i<V.size();i++)
    {
        done[eu[V[i]]]=done[ev[V[i]]]=1;
    }
    if(rep[0]!=rep[1])
    {
        if(rep[0]>rep[1])
        {
            for(int i=0;i<V.size();i++)
            {
                int idx=V[i];
                if(!ety[idx])
                {
                    ans[ev[idx]>>1]=id[ev[V[(i+1)%V.size()]]];
                }
            }
        }
        else
        {
            for(int i=0;i<V.size();i++)
            {
                int idx=V[i];
                if(!ety[idx])
                {
                    ans[ev[idx]>>1]=id[ev[V[(i-1+V.size())%V.size()]]];
                }
            }
        }
    }
    else
    {
        int minval=1e9,loc=-1;
        int cur=0;
        for(int i=0;i<V.size();i++)
        {
            int idx=V[i];
            cur+=w[idx]?1:-1;
            if(cur<minval)
            {
                minval=cur;
                loc=i;
            }
        }
        vector<int>V2;
        for(int i=(loc+1)%V.size();i!=loc;i=(i+1)%V.size())
        {
            V2.push_back(V[i]);
        }
        V2.push_back(V[loc]);
        vector<int>V3;
        for(int i=0;i<V2.size();i++)
        {
            int idx=V2[i];
            if(w[idx])V3.push_back(V2[i]);
            else
            {
                int id1=V2[i],id2=V3.back();
                if(ety[id1])swap(id1,id2);
                ans[ev[id1]>>1]=id[ev[id2]];
                V3.pop_back();
            }
        }
    }
}
int main()
{
    freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);
    scanf("%d",&n);
    for(int i=0;i<n+n;i++)
    {
        int ty,u;
        scanf("%d%d",&ty,&u);
        u--;
        id[i]=u<<1|ty;  
        rev[u<<1|ty]=i;
    }

    ne=0;
    for(int i=0;i<n;i++)
    {
        add(i<<1,i<<1|1,0);
    }
    for(int i=0;i<n;i++)
    {
        int u=rev[i<<1],v=rev[i<<1|1];
        add(u,v,1);
    }

    for(int i=0;i<n+n;i++)
    {
        if(!done[i])
        {
            solve(i);
        }
    }

    for(int i=0;i<n;i++)printf("%d\n",(ans[i]>>1)+1);
}

C:

#include<bits/stdc++.h>
using namespace std;
const int Maxn=555;
typedef vector<int> vv;
typedef set<int>ss;
typedef set<int>::iterator iter;
typedef pair<int,ss> pi;
bool operator<(const ss&a,const ss&b)
{
    if(a.size()!=b.size())return a.size()<b.size();
    for(iter it1=a.begin(),it2=b.begin();it1!=a.end();it1++,it2++)
    {
        if(*it1!=*it2)return *it1<*it2;
    }
    return 0;
}
int col[Maxn],id[Maxn],f[Maxn];
map<pi,int>Mp;
vv G[Maxn];
ss dp[Maxn];
int n;
int tot,cnt;
bool fuck;
void debug(){puts("wa");exit(0);}
int getcol()
{
    return rand()%tot+1;
}
int getid(int x)
{
    if(Mp.find(pi(col[x],dp[x]))==Mp.end())
    {
        Mp[pi(col[x],dp[x])]=++cnt;
        return cnt;
    }
    return Mp[pi(col[x],dp[x])];
}

bool dfs2(int u,int st)
{
    for(int i=1;i<=tot;i++)
    {
        if(col[u]==i)continue;
        if(Mp.find(pi(i,dp[u]))==Mp.end())
        {
            Mp[pi(i,dp[u])]=++cnt;
            col[u]=i;
            id[u]=cnt;
            return 1;
        }
        else
        {
            int nid=Mp[pi(i,dp[u])];
            bool flag=1;
            int tpid=nid;
            for(int j=u;j!=st;j=f[j])
            {
                if(dp[f[j]].find(tpid)!=dp[f[j]].end()){flag=0;break;}
                if(f[j]==st)break;
                int storeid=id[j];
                dp[f[j]].erase(storeid);
                dp[f[j]].insert(tpid);
                if(Mp.find(pi(col[f[j]],dp[f[j]]))==Mp.end())
                {
                    dp[f[j]].erase(tpid);
                    dp[f[j]].insert(storeid);
                    break;
                }
                int nxtid=getid(f[j]);
                dp[f[j]].erase(tpid);
                dp[f[j]].insert(storeid);
                tpid=nxtid;
            }
            if(flag)
            {
                col[u]=i;
                id[u]=nid;
                return 1;
            }
        }
    }
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        int tpid=id[v];
        if(dfs2(v,st))
        {
            dp[u].erase(tpid);
            dp[u].insert(id[v]);
            id[u]=getid(u);
            return 1;
        }
    }
    return 0;
}
bool dfs(int u)
{
    col[u]=getcol();
    dp[u].clear();
    for(int i=0;i<G[u].size();i++)
    {
        int v=G[u][i];
        if(!dfs(v))return 0;
        if(dp[u].find(id[v])!=dp[u].end())
        {
            if(!dfs2(v,u))return 0;
        }
        dp[u].insert(id[v]);
    }
    id[u]=getid(u);
    if(fuck&&u==1)
    {
        printf("dp1.size=%d G1.size=%d\n",(int)dp[1].size(),(int)G[1].size());
    }
    return 1;
}
bool check(int mid)
{
    tot=mid;
    Mp.clear();
    cnt=0;
    if(dfs(1))return 1;
    return 0;
}
int main()
{
    freopen("doityourself.in","r",stdin);
    freopen("doityourself.out","w",stdout);
    //srand(time(NULL));
    scanf("%d",&n);
    for(int i=2;i<=n;i++)
    {
        int x;scanf("%d",&x);
        f[i]=x;
        G[x].push_back(i);
    }
    if(check(1))
    {
        puts("1");
        for(int i=1;i<=n;i++)
            printf("1%c",i==n?'\n':' ');
        return 0;
    }
    int L=1,R=n;
    while(L+1<R)
    {
        int mid=(L+R)>>1;
        if(check(mid))R=mid;
        else L=mid;
    }
    check(R);
    check(R);
    for(int i=1;i<=n;i++)
    {
        if(G[i].size()!=dp[i].size())
        {
            fuck=1;
            check(R);
            printf("%d %d\n",(int)G[1].size(),(int)dp[1].size());
            return 0;
        }
    }
    printf("%d\n",R);
    for(int i=1;i<=n;i++)
    {
        printf("%d%c",col[i],i==n?'\n':' ');
    }
}

D:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 5005 ;
const int INF = 0x3f3f3f3f ;

LL n ;
int w[10000][2] ;
LL dp[100][100] ;

int solve () {
    int k = 0 ;
    for ( int i = 2 ; i <= 1000000 ; ++ i ) {
        if ( n % i == 0 ) {
            while ( n % i == 0 ) {
                k ++ ;
                n /= i ;
            }
            break ;
        }
    }
    if ( !k ) printf ( "1\n" ) ;
    else {
        int m = 0 ;
        for ( int i = 0 ; i <= k ; ++ i ) {
            for ( int j = 0 ; j <= k ; ++ j ) if ( i || j ) {
                w[m][0] = i ;
                w[m][1] = j ;
                ++ m ;
            }
        }
        clr ( dp , 0 ) ;
        dp[0][0] = 1 ;
        for ( int i = 0 ; i < m ; ++ i ) {
            for ( int x = w[i][0] ; x <= k ; ++ x ) {
                for ( int y = w[i][1] ; y <= k ; ++ y ) {
                    dp[x][y] += dp[x - w[i][0]][y - w[i][1]] ;
                }
            }
        }
        printf ( "%lld\n" , dp[k][k] - 1 ) ;
    }
}

int main () {
    freopen ( "false.in" , "r" , stdin ) ;
    freopen ( "false.out" , "w" , stdout ) ;
    while ( ~scanf ( "%lld" , &n ) ) solve () ;
    return 0 ;
}

E:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 405 ;
const int INF = 0x3f3f3f3f ;

struct Node {
    int nxt , val ;
} ;

Node node[MAXN] ;
int cur ;
int G[MAXN][MAXN] ;
int a[MAXN][MAXN] , cnt[MAXN] ;
int n , k ;

void solve () {
    for ( int i = 1 ; i <= n ; ++ i ) {
        getchar () ;
        for ( int j = 1 ; j <= n ; ++ j ) {
            char c = getchar () ;
            G[i][j] = c == '-' ;
        }
    }
    for ( int i = 1 ; i < n ; ++ i ) {
        G[i][n] = 1 ;
    }
    for ( int i = 1 ; i <= k ; ++ i ) {
        for ( cnt[i] = 0 ; ; cnt[i] ++ ) {
            scanf ( "%d" , &a[i][cnt[i]] ) ;
            if ( a[i][cnt[i]] == n ) break ;
        }
        -- cnt[i] ;
    }
    for ( int i = 0 ; i <= cnt[1] ; ++ i ) {
        ++ cur ;
        node[cur].nxt = cur + 1 ;
        node[cur].val = a[1][i] ;
    }
    ++ cur ;
    node[cur].nxt = 0 ;
    node[cur].val = n ;
    for ( int i = 2 ; i <= k ; ++ i ) {
        for ( int j = 1 , o = 1 ; j <= cnt[i] ; ++ j ) {
            for ( ; node[o].nxt ; o = node[o].nxt ) {
                int x = node[o].val ;
                int y = node[node[o].nxt].val ;
                int z = a[i][j] ;
                if ( G[x][z] && G[z][y] ) {
                    ++ cur ;
                    node[cur].nxt = node[o].nxt ;
                    node[o].nxt = cur ;
                    node[cur].val = z ;
                    o = cur ;
                    break ;
                }
            }
        }
    }
    for ( int o = 1 ; node[o].nxt ; o = node[o].nxt ) {
        printf ( "%d " , node[o].val ) ;
    }
    printf ( "%d\n" , n ) ;
}

int main () {
    freopen ( "inspection.in" , "r" , stdin ) ;
    freopen ( "inspection.out" , "w" , stdout ) ;
    while ( ~scanf ( "%d%d" , &n , &k ) ) solve () ;
    return 0 ;
}

F:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 405 ;
const int INF = 0x3f3f3f3f ;
const double eps = 1e-10 ;

struct Point {
    int x , y ;
    Point () {}
    Point ( int x , int y ) : x ( x ) , y ( y ) {}
    Point operator - ( const Point& b ) const {
        return Point ( x - b.x , y - b.y ) ;
    }
    int len2 () {
        return x * x + y * y ;
    }
} ;

struct Node {
    int v , dis ;
    double r ;
    Node () {}
    Node ( int v , double r , int dis ) : v ( v ) , r ( r ) , dis ( dis ) {}
    bool operator < ( const Node& a ) const {
        return r < a.r ;
    }
} ;

Point p[MAXN] ;
vector < Node > X[MAXN] , Y[MAXN] ;
int pre[2][MAXN][MAXN][2] ;
int n , m ;
double dp[MAXN][MAXN] ;
bool vis[MAXN][MAXN] ;
int ans1 , ans2 , ways ;
vector < int > S1 , S2 ;

int sgn ( double x ) {
    return ( x > eps ) - ( x < -eps ) ;
}

double dfs ( int x , int y , vector < Node > G[] , int f ) {
    if ( vis[x][y] ) return dp[x][y] ;
    vis[x][y] = 1 ;
    double ans = 0 ;
    for ( int i = 0 , j = 0 ; i < G[x].size () ; ++ i ) {
        while ( j < G[y].size () && G[y][j].r < G[x][i].r ) ++ j ;
        if ( j == G[y].size () ) break ;
        if ( G[x][i].dis != G[y][j].dis || sgn ( G[y][j].r - G[x][i].r ) ) continue ;
        double tmp = sqrt ( 0.0 + G[x][i].dis ) + dfs ( G[x][i].v , G[y][j].v , G , f ) ;
        if ( ans < tmp ) {
            ans = tmp ;
            pre[f][x][y][0] = G[x][i].v ;
            pre[f][x][y][1] = G[y][j].v ;
        }
    }
    return dp[x][y] = ans ;
}

int get ( int f , int x , int y ) {
    S1.push_back ( x ) ;
    S2.push_back ( y ) ;
    if ( pre[f][x][y][0] ) return get ( f , pre[f][x][y][0] , pre[f][x][y][1] ) + 1 ;
    return 1 ;
}

void solve () {
    int x , y ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        scanf ( "%d%d" , &p[i].x , &p[i].y ) ;
        X[i].clear () ;
        Y[i].clear () ;
    }
    for ( int i = 1 ; i <= m ; ++ i ) {
        scanf ( "%d%d" , &x , &y ) ;
        if ( p[x].x > p[y].x ) swap ( x , y ) ;
        if ( p[x].x < p[y].x ) {
            double r = atan2 ( p[y].y - p[x].y , p[y].x - p[x].x ) ;
            X[x].push_back ( Node ( y , r , ( p[y] - p[x] ).len2 () ) ) ;
        }
        if ( p[x].y > p[y].y ) swap ( x , y ) ;
        if ( p[x].y < p[y].y ) {
            double r = atan2 ( p[y].y - p[x].y , p[y].x - p[x].x ) ;
            Y[x].push_back ( Node ( y , r , ( p[y] - p[x] ).len2 () ) ) ;
        }
    }
    for ( int i = 1 ; i <= n ; ++ i ) {
        sort ( X[i].begin () , X[i].end () ) ;
        sort ( Y[i].begin () , Y[i].end () ) ;
    }
    double ans = 0 , ans1 , ans2 ;
    clr ( vis , 0 ) ;
    clr ( pre , 0 ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        for ( int j = 1 ; j <= n ; ++ j ) if ( i != j && !vis[i][j] ) {
            dp[i][j] = dfs ( i , j , X , 0 ) ;
            if ( ans < dp[i][j] ) {
                ans = dp[i][j] ;
                ans1 = i ;
                ans2 = j ;
                ways = 0 ;
            }
        }
    }
    clr ( vis , 0 ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        for ( int j = 1 ; j <= n ; ++ j ) if ( i != j && !vis[i][j] ) {
            dp[i][j] = dfs ( i , j , Y , 1 ) ;
            if ( ans < dp[i][j] ) {
                ans = dp[i][j] ;
                ans1 = i ;
                ans2 = j ;
                ways = 1 ;
            }
        }
    }
    if ( ans < eps ) printf ( "%.10f\n" , 0.0 ) ;
    else {
        S1.clear () ;
        S2.clear () ;
        int cnt = get ( ways , ans1 , ans2 ) ;
        printf ( "%.10f\n" , ans ) ;
        printf ( "%d\n" , cnt ) ;
        for ( int i = 0 ; i < cnt ; ++ i ) {
            printf ( "%d%c" , S1[i] , i < cnt - 1 ? ' ' : '\n' ) ;
        }
        for ( int i = 0 ; i < cnt ; ++ i ) {
            printf ( "%d%c" , S2[i] , i < cnt - 1 ? ' ' : '\n' ) ;
        }
    }
}

int main () {
    freopen ( "london.in" , "r" , stdin ) ;
    freopen ( "london.out" , "w" , stdout ) ;   
    while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ;
    return 0 ;
}

G:

#include<bits/stdc++.h>
using namespace std;
int n,k,p;
string s[12];
string dp[2][12];
int main()
{
    freopen("morpher.in","r",stdin);
    freopen("morpher.out","w",stdout);
    scanf("%d%d%d",&n,&k,&p);
    for(int i=0;i<=n;i++)cin>>s[i];
    for(int i=0;i<=n;i++)
    {
        if(s[i].size()>p)s[i].resize(p);
        dp[0][i]=s[i];
    }
    int cs=0;
    for(;k;)
    {
        if(k&1)
        {
            string nxt;
            for(int i=0;nxt.size()<p&&i<s[0].size();i++)
            {
                nxt+=dp[cs][s[0][i]-'A'+1];
            }
            if(nxt.size()>p)nxt.resize(p);
            s[0]=nxt;
        }
        for(int i=1;i<=n;i++)
        {
            dp[cs^1][i]="";
            for(int j=0;dp[cs^1][i].size()<p&&j<dp[cs][i].size();j++)
            {
                dp[cs^1][i]+=dp[cs][dp[cs][i][j]-'A'+1];
            }
            if(dp[cs^1][i].size()>p)dp[cs^1][i].resize(p);
        }
        cs^=1;
        k>>=1;
    }
    //cout<<s[0]<<endl;
    if(s[0].size()>=p)printf("%c\n",s[0][p-1]);
    else puts("-");
}

H:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 233333 ;
const int INF = 0x3f3f3f3f ;

struct Node {
    Node* c[2] , *f ;
    int s , v ;
    int minv ;

    void up () {
        s = c[0]->s + c[1]->s + 1 ;
        minv = min ( v , min ( c[0]->minv , c[1]->minv ) ) ;
    }
} Tnull , *null = &Tnull ;

struct Splay {
    Node node[MAXN] , *cur ;
    Node* root ;

    void clear () {
        null->s = 0 ;
        null->v = -1 ;
        null->minv = INF ;
        cur = node ;
        root = null ;
    }

    Node* newNode ( int v , Node* f ) {
        cur->v = v ;
        cur->s = 1 ;
        cur->minv = v ;
        cur->c[0] = cur->c[1] = null ;
        cur->f = f ;
        return cur ++ ;
    }

    void rot ( Node* o , bool d ) {
        Node* p = o->f ;
        p->c[!d] = o->c[d] ;
        if ( o->c[d] != null ) o->c[d]->f = p ;
        o->f = p->f ;
        if ( p->f != null ) {
            if ( p == p->f->c[0] ) p->f->c[0] = o ;
            else p->f->c[1] = o ;
        }
        o->c[d] = p ;
        p->f = o ;
        p->up () ;
        if ( root == p ) root = o ;
    }

    void splay ( Node* o , Node* f ) {
        while ( o->f != f ) {
            Node* p = o->f ;
            if ( p->f == f ) rot ( o , o == p->c[0] ) ;
            else {
                if ( p == p->f->c[0] ) {
                    if ( o == p->c[0] ) rot ( p , 1 ) , rot ( o , 1 ) ;
                    else rot ( o , 0 ) , rot ( o , 1 ) ;
                } else {
                    if ( o == p->c[1] ) rot ( p , 0 ) , rot ( o , 0 ) ;
                    else rot ( o , 1 ) , rot ( o , 0 ) ;
                }
            }
        }
        o->up () ;
    }

    void select ( int k , Node* f ) {
        Node* o = root ;
        ++ k ;
        while ( o != null ) {
            int s = o->c[0]->s ;
            if ( k == s + 1 ) break ;
            if ( k <= s ) o = o->c[0] ;
            else {
                k -= s + 1 ;
                o = o->c[1] ;
            }
        }
        splay ( o , f ) ;
    }

    Node* get ( int l , int r ) {
        select ( l - 1 , null ) ;
        select ( r + 1 , root ) ;
        return root->c[1]->c[0] ;
    }

    void insert ( int pos , int v ) {
        get ( pos + 1 , pos ) ;
        Node* o = newNode ( v , root->c[1] ) ;
        root->c[1]->c[0] = o ;
        root->c[1]->up () ;
        root->up () ;
    }
    void init () {
        clear () ;
        root = newNode ( INF , null ) ;
        root->c[1] = newNode ( INF , root ) ;
    }
} T ;

int n , siz ;

void show () {
    for ( int i = 1 ; i <= siz ; ++ i ) {
        printf ( "%d " , T.get ( i , i )->v ) ;
    }
    puts ( "" ) ;
}

void solve () {
    char op ;
    int x , y ;
    T.init () ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        scanf ( " %c%d%d" , &op , &x , &y ) ;
        if ( op == '+' ) T.insert ( x , y ) , ++ siz ;
        else printf ( "%d\n" , T.get ( x , y )->minv ) ;
    //  show () ;
    }
}

int main () {
    freopen ( "rmq.in" , "r" , stdin ) ;
    freopen ( "rmq.out" , "w" , stdout ) ;  
    while ( ~scanf ( "%d" , &n ) ) solve () ;
    return 0 ;
}

I:

#include <bits/stdc++.h>
using namespace std ;

typedef long long LL ;

#define clr( a , x ) memset ( a , x , sizeof a )

const int MAXN = 505 ;
const int MAXE = 1000005 ;

struct Edge {
    int v , n ;
    Edge () {}
    Edge ( int v , int n ) : v ( v ) , n ( n ) {}
} ;

Edge E[MAXE] ;
int H[MAXN] , cntE ;
int vis[MAXN] , Time ;
int G[MAXN][MAXN] ;
int a[MAXN][4] ;
int use[MAXN] ;
int Ly[MAXN] ;
int c[MAXN] ;
int n , k ;

void init () {
    cntE = 0 ;
    clr ( H , -1 ) ;
}

void addedge ( int u , int v ) {
    E[cntE] = Edge ( v , H[u] ) ;
    H[u] = cntE ++ ;
}

int dfs ( int u ) {
    for ( int i = H[u] ; ~i ; i = E[i].n ) if ( vis[E[i].v] != Time ) {
        int v = E[i].v ;
        vis[v] = Time ;
        if ( Ly[v] == -1 || dfs ( Ly[v] ) ) {
            Ly[v] = u ;
            return 1 ;
        }
    }
    return 0 ;
}

int match () {
    int ans = 0 ;
    Time = 0 ;
    clr ( Ly , -1 ) ;
    clr ( vis , 0 ) ;
    for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 1 && use[i] ) {
        ++ Time ;
        ans += dfs ( i ) ;
    }
    return ans ;
}

bool check ( int x1 , int y1 , int z1 , int x2 , int y2 , int z2 ) {
    if ( x1 == x2 && y1 == y2 && abs ( z1 - z2 ) == 1 ) return 1 ;
    if ( x1 == x2 && z1 == z2 && abs ( y1 - y2 ) == 1 ) return 1 ;
    if ( y1 == y2 && z1 == z2 && abs ( x1 - x2 ) == 1 ) return 1 ;
    return 0 ;
}

void paint ( int u ) {
    for ( int i = 1 ; i <= n ; ++ i ) if ( G[u][i] ) {
        if ( !c[i] ) {
            c[i] = 3 - c[u] ;
            paint ( i ) ;
        }
    }
}

int build ( int lim ) {
    init () ;
    clr ( G , 0 ) ;
    for ( int i = 1 ; i <= n ; ++ i ) {
        for ( int j = 1 ; j <= n ; ++ j ) if ( i != j ) {
            if ( check ( a[i][0] , a[i][1] , a[i][2] , a[j][0] , a[j][1] , a[j][2] ) ) {
                if ( a[i][3] + a[j][3] >= lim ) G[i][j] = G[j][i] = 1 ;
            }
        }
    }
    clr ( c , 0 ) ;
    for ( int i = 1 ; i <= n ; ++ i ) if ( !c[i] ) {
        c[i] = 1 ;
        paint ( i ) ;
    }
    clr ( use , 0 ) ;
    int cnt = n ;
    for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 1 ) {
        for ( int j = 1 ; j <= n ; ++ j ) if ( c[j] == 2 && G[i][j] ) {
            addedge ( i , j ) ;
            use[i] = use[j] = 1 ;
        }
    }
    for ( int i = 1 ; i <= n ; ++ i ) if ( !use[i] ) {
        cnt -- ;
        if ( a[i][3] < lim ) return -1 ;
    }
    return cnt ;
}

void put ( int x1 , int y1 , int z1 , int x2 , int y2 , int z2 ) {
    if ( x1 == x2 && y1 == y2 && abs ( z1 - z2 ) == 1 ) {
        printf ( "%d %d %.1f\n" , x1 , y1 , ( z1 + z2 ) / 2.0 ) ;
    }
    if ( x1 == x2 && z1 == z2 && abs ( y1 - y2 ) == 1 ) {
        printf ( "%d %.1f %d\n" , x1 , ( y1 + y2 ) / 2.0 , z1 ) ;
    }
    if ( y1 == y2 && z1 == z2 && abs ( x1 - x2 ) == 1 ) {
        printf ( "%.1f %d %d\n" , ( x1 + x2 ) / 2.0 , y1 , z1 ) ;
    }
}

void solve () {
    for ( int i = 1 ; i <= n ; ++ i ) {
        scanf ( "%d%d%d%d" , &a[i][0] , &a[i][1] , &a[i][2] , &a[i][3] ) ;
    }
    int l = 1 , r = 1e9 ;
    while ( l < r ) {
        int m = l + r + 1 >> 1 ;
        int x = build ( m ) ;
        if ( ~x ) {
            int y = match () ;
            if ( n - y <= k ) l = m ;
            else r = m - 1 ;
        } else r = m - 1 ;
    }
    int x = build ( l ) ;
    if ( x == -1 ) printf ( "-1\n" ) ;
    else {
        int y = match () ;
        /*
        printf ( "%d %d\n" , x , y ) ;
        for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 1 ) {
            for ( int j = H[i] ; ~j ; j = E[j].n ) {
                printf ( "%d %d %d\n" , i , E[j].v , G[i][E[j].v] ) ;
            }
        }
        */
        if ( n - y > k ) printf ( "-1\n" ) ;
        else {
            printf ( "%d %d\n" , n - y , l ) ;
            clr ( vis , 0 ) ;
            for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 2 ) {
                if ( Ly[i] != -1 ) {
                    int t = Ly[i] ;
                    vis[t] = 1 ;
                    put ( a[t][0] , a[t][1] , a[t][2] , a[i][0] , a[i][1] , a[i][2] ) ;
                } else {
                    for ( int j = 1 ; j <= n ; ++ j ) {
                        if ( !G[j][i] ) continue ;
                        put ( a[i][0] , a[i][1] , a[i][2] , a[j][0] , a[j][1] , a[j][2] ) ;
                        break ;
                    }
                }
            }
            for ( int i = 1 ; i <= n ; ++ i ) if ( c[i] == 1 && use[i] && !vis[i] ) {
                for ( int j = 1 ; j <= n ; ++ j ) if ( G[i][j] ) {
                    put ( a[i][0] , a[i][1] , a[i][2] , a[j][0] , a[j][1] , a[j][2] ) ;
                    break ;
                }
            }
            for ( int i = 1 ; i <= n ; ++ i ) if ( use[i] == 0 ) {
                printf ( "%d %d %d\n" , a[i][0] , a[i][1] , a[i][2] ) ;
            }
        }
    }
}

int main () {
    freopen ( "starbugs.in" , "r" , stdin ) ;
    freopen ( "starbugs.out" , "w" , stdout ) ;     
    while ( ~scanf ( "%d%d" , &n , &k ) ) solve () ;
    return 0 ;
}
發佈了55 篇原創文章 · 獲贊 2 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章