Codeforces Round #743 (Div. 2)

B

很明显,第一位肯定是能比较出大小的

然后1 换a过来,2 换b过来 3 a也换b也换

 

法1

当时的乱搞写法

存下位置,排序值,st表找合适值域中位置最小值

int n,a[N],lg[N],minn[N][50],ans;
struct node {
    int val;
    int pos;
    bool operator<(const node &rhs)const{
        return val<rhs.val;
    }
}b[N];
void solve(){
    lg[0]=-1;
    ans=inf;
    scanf("%lld",&n);
    for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
    for(int i=1;i<=n;++i){
        lg[i]=lg[i/2]+1;
        scanf("%lld",&b[i].val);
        b[i].pos=i; 
    }
    sort(b+1,b+1+n);
    for(int i=1;i<=n;i++){
        minn[i][0]=b[i].pos;
    }
    for(int i=1;i<=lg[n];i++){
        for(int j=1;j+(1<<i)-1<=n;j++){
            minn[j][i]=min(minn[j][i-1],minn[j+(1<<(i-1))][i-1]);
        }
    }
    for(int i=1;i<=n;i++){
        int l=(a[i]+1)/2;
        int r=n;
        int len=lg[r-l+1];
        ans=min(ans,i-2+min(minn[l][len],minn[r-(1<<(len))+1][len]));
    }
    printf("%lld\n",ans);    
}

法2

按ai的值上升,找合适的bi

类似于单调栈的感觉

对于ai值从小到大,bi的位置一定是单调上升的

证明

假设当前ai值 为 x  找到 b的pos为合适

若bpos 小于x + 2  pos后移

若bpos 大于x + 2  pos不变

假设pos点不是最优的,pos位置前存在 pos‘ 使得 bpos’ 大于 x

根据前面的移动规则, 指针不会移动到pos位置,因为 bpos’  指针会停留在pos‘

得到pos点最优

  for(int i=0;i<n;i++) cin>>a[i]; 
  for(int i=0;i<n;i++) cin>>b[i];   int ans = n;   for(int i=1, j=0;i<2*n;i+=2)   {     while(b[j]<i) j++;     c[i] = j;   }   for(int i=0;i<n;i++)     ans = min(ans, c[a[i]]+ i);

 

 

C

记录一下 轮数 和 编号

然后优先队列保证小轮数先更新 

章节编号大的同一轮

编号小的 下一轮

 

 

#include<bits/stdc++.h>
#define inf 1e18
#define ll long long 
#define ull unsigned long long 
#define int long long
#define PI acos(-1.0)
#define PII pair<int,int>
using namespace std;
const int N = 1e6+7 , M = N * 2;
const int p = 998244353;
int num,x,n,ans;
int in[N];
int h[N], e[N], ne[N], idx;

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
}

bool topo(){
    priority_queue<PII, vector<PII>, greater< PII > > q;
    int cnt = 0;
    for(int i = 1; i <= n ;++i){
        if(in[i] == 0){
            cnt++;
            q.push({1,i});
        }
    }
    while(!q.empty()){
        ans = q.top().first;
        int pos = q.top().second;
        q.pop();
        for (int i = h[pos]; i != -1; i = ne[i])
        {
            int j = e[i];
            --in[j];
            if(in[j] == 0)
            {
                cnt++;
                if(j > pos) q.push({ans,j});
                else        q.push({ans+1,j});
            }
        }
    }
    //cout << n << cnt <<" ---\n";
    return cnt == n ;
}
void solve(){
    ans=-1;idx=0;
    scanf("%lld",&n);
    for(int i=1;i<=n;++i) h[i] = -1;
    for(int i=1;i<=n;++i){
        scanf("%lld%",&num);
        in[i]=num;
        while(num--){
            scanf("%lld",&x);
            add(x,i);
        }
    }
    if(topo())    printf("%lld\n",ans);
    else        printf("-1\n");
}
signed main(){
    int t=1;
       scanf("%lld",&t);
    while(t--){
        solve();
    }
    return 0;
}

 

posted @ 2021-09-21 21:59  PdrEam  阅读(62)  评论(0编辑  收藏  举报