gym101987部分简要题解

A. Circuits

问题等价于线段和直线的相交问题。设两条直线分别是y=a和y=b。先把n条线段都塞进线段树。枚举a的时候,把和y=a相交的线段都从线段树里去掉,线段树上保留不和a相交的线段,然后查全局最大值。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 4e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n , c[maxn] ;
int nxt[maxn] , lst[maxn] ;
struct node
{
    int x , y , f ;
    int id ;
    bool operator < (const node &s) const
    {
        return x < s.x ;
    }
} a[maxn] ;
bool cmp(node s , node t)
{
    if(s.id != t.id)  return s.id < t.id ;
    else  return s.f > t.f ;
}
struct seg_tree
{
    int max1[maxn << 2] , lazy[maxn << 2] ;  
    int ls(int x){ return x << 1 ; }
    int rs(int x){ return x << 1 | 1 ; }
    void push_up(int p){ max1[p] = max(max1[ls(p)] , max1[rs(p)]) ; }
    void build(int id , int l , int r)
    {
        lazy[id] = 0 ;
        if(l == r) {max1[id] = c[l] ; return ;}
        int mid = (l + r) >> 1 ;
        build(ls(id) , l , mid) ;
        build(rs(id) , mid + 1 , r) ;
        push_up(id) ;
    } 
    void f(int id , int l , int r , int k)
    {
        lazy[id] += k ;
        max1[id] += k ;
    }
    void push_down(int id , int l , int r)
    {
        int mid = (l + r) >> 1 ;
        f(ls(id) , l , mid , lazy[id]) ;
        f(rs(id) , mid + 1 , r , lazy[id]) ;
        lazy[id] = 0 ;
    }
    void add(int id , int l , int r , int x , int y , int k)
    {
        if(x > y || x > r || y < l)  return ;
        if(x <= l && r <= y)
        {
            max1[id] += k ;
            lazy[id] += k ;
            return ;
        }
        push_down (id , l , r) ;
        int mid = (l + r) >> 1 ;
        if(x <= mid)  add(ls(id) , l , mid , x , y , k) ;
        if(y > mid)   add(rs(id) , mid + 1 , r , x , y , k) ;
        push_up(id) ;
    }
    int query(int id , int l , int r , int x , int y)
    {
        if(x > y || x > r || y < l)  return inf ;
        int ans = 0 ;
        if(x <= l && r <= y) return max1[id] ; 
        int mid = (l + r) >> 1 ;
        push_down(id , l , r) ;
        if(x <= mid) ans = max(ans , query(ls(id) , l , mid , x , y)) ;
        if(y > mid)  ans = max(ans , query(rs(id) , mid + 1 , r , x , y)) ;
        return ans ;
    }
} seg ;
int main()
{
    ios ;
    cin >> n ;
    rep(i , 1 , n)
    {
        int u1 , v1 , u2 , v2 ;
        cin >> u1 >> v1 >> u2 >> v2 ;
        a[i * 2 - 1].x = v2 ;
        a[i * 2 - 1].f = 1 ;
        a[i * 2 - 1].id = i ;
        a[i * 2].x = v1 + 1 ;
        a[i * 2].f = -1 ;
        a[i * 2].id = i ;
    }
    sort(a + 1 , a + 2 * n + 1) ;
    int now = 0 ;
    rep(i , 1 , 2 * n)
    {
        now ++ ;
        int j = i ;
        while(j + 1 <= 2 * n && a[j + 1].x == a[j].x)  j ++ ;
        rep(k , i , j)  a[k].y = now ;
        i = j ;
    }
    sort(a + 1 , a + 2 * n + 1 , cmp) ;
    rep(i , 1 , n)  nxt[i] = a[i * 2].y , lst[i] = a[i * 2 - 1].y ;
    rep(i , 1 , n * 2)  c[a[i].y] += a[i].f ;
    rep(i , 1 , now)  c[i] += c[i - 1] ;
    rep(i , 1 , now)  seg.add(1 , 1 , now , i , i , c[i]) ;//, ddebug(i , c[i]) ;
    sort(a + 1 , a + 2 * n + 1) ;
    int res = 0 ;
    int ans = 0 ;
    rep(i , 1 , 2 * n)
    {
        int j = i ;
        while(j + 1 <= 2 * n && a[j + 1].y == a[j].y)  j ++ ;
        rep(k , i , j)
        {
            res += a[k].f ;
            if(a[k].f == -1)  seg.add(1 , 1 , now , lst[a[k].id] , a[k].y - 1 , 1) ;
            else  seg.add(1 , 1 , now , a[k].y , nxt[a[k].id] - 1 , -1) ;
        }
        i = j ;
        ans = max(ans , res + seg.max1[1]) ;
        //ddebug(a[i].y , res + seg.max1[1]) ;
    }
    cout << ans << '\n' ;
    return 0 ;
}

B. Cosmetic Survey

题意转化一下就是最大化a到b的路径上的边的最小值。floyd即可。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 500 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int m , n ;
int c[maxn][maxn] ;
int d[maxn][maxn] ;
int s[maxn][maxn] ;
bool vis[maxn] ;
vector<pii> g[maxn] ;
int main()
{
    ios ;
    cin >> m >> n ;
    rep(i , 1 , n)  rep(j , 1 , m)  cin >> c[i][j] ;
    rep(i , 1 , n)  rep(j , 1 , m)  if(c[i][j] == 0)  c[i][j] = 1e7 ;
    rep(i , 1 , m)  rep(j , 1 , m)
    {
        int x = 0 , y = 0 ;
        rep(k , 1 , n)  if(c[k][i] < c[k][j])  x ++ ; else if(c[k][j] < c[k][i])  y ++ ;
        if(x > y)  d[i][j] = x ;
        else if(x < y)  d[j][i] = y ;
    }
    rep(k , 1 , m)  rep(i , 1 , m)  rep(j , 1 , m)  d[i][j] = max(d[i][j] , min(d[i][k] , d[k][j])) ;
    rep(i , 1 , m)
    {
        bool flag = 1 ;
        rep(j , 1 , m)  if(j != i && d[i][j] < d[j][i])  flag = 0 ;
        if(flag)  cout << i << ' ' ;
    }
    cout << '\n' ;
    return 0 ;
}

D. Go Latin

模拟。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
char s[maxn] ;
map<string , string> id ;
void init()
{
    id["a"] = "as" ;
    id["i"] = "ios" , id["y"] = "ios" ;
    id["l"] = "les" ;
    id["n"] = "anes" , id["ne"] = "anes" ;
    id["o"] = "os" ;
    id["r"] = "res" ;
    id["t"] = "tas" ;
    id["u"] = "us" ;
    id["v"] = "ves" ;
    id["w"] = "was" ;
}
void solve()
{
    int len ;
    cin >> s + 1 ;
    len = strlen(s + 1) ;
    if(len >= 1)
    {
        string t = "" ;
        t += s[len] ;
        if(id.count(t))
        {
            rep(i , 1 , len - 1)  cout << s[i] ;
            cout << id[t] << '\n' ;
            return ;
        }       
    }
    if(len >= 2)
    {
        string t = "" ;
        t += s[len - 1] ;
        t += s[len] ;
        if(id.count(t))
        {
            rep(i , 1 , len - 2)  cout << s[i] ;
            cout << id[t] << '\n' ;
            return ;
        }   
    }
    rep(i , 1 , len)  cout << s[i] ;
    cout << "us\n" ;
}
int main()
{
    ios ;
    init() ;
    int T ;
    cin >> T ;
    while(T --)  solve() ;
    return 0 ;
}

E. LED

二分答案。check(t)的时候模拟整个过程,如果产生的区间多于3个,就放大t,否则缩小t。

坑点:1.double会卡常数,所以要用longlong 2.a[i].x=0时答案最少是a[i].y

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 3e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n ;
struct node
{
    ll x , y ;
    bool operator < (const node &s) const
    {
        return x < s.x ;
    }
} a[maxn] ;
bool ok(ll t)
{
    int tmp1 = 0 , tmp2 = 0 , tmp3 = 0 ;
    rep(i , 1 , n)  if(a[i].y <= t)  tmp1 = i ;  else  break ;
    if(tmp1 == n)  return 1 ;
    ll mn = 1e10 , mx = 0 ;
    ll l1 = 0 , l2 = 0 ;
    rep(i , tmp1 + 1 , n)
    {
        mn = min(mn , a[i].y) ;
        mx = max(mx , a[i].y) ;
        if(mx - mn <= 2 * t)  tmp2 = i ;
        else  break ;
    }
    if(tmp2 == 0)  return 0 ;
    if(tmp2 == n)  return 1 ;
    l1 = (mx + mn) / 2 ;

    mn = 1e10 , mx = 0 ;
    rep(i , tmp2 + 1 , n)
    {
        mn = min(mn , a[i].y) ;
        mx = max(mx , a[i].y) ;
        if(mx - mn <= 2 * t)  tmp3 = i ;
        else  break ;
    }
    l2 = (mx + mn) / 2 ;

    if(tmp3 != n || l1 > l2)  return 0 ;
    return 1 ;
}
int main()
{
    ios ;
    ll base = 0 ;
    cin >> n ;
    rep(i , 1 , n)  cin >> a[i].x >> a[i].y , a[i].y *= 10 ;
    rep(i , 1 , n)  if(a[i].x == 0)  base = max(base , a[i].y) ;
    sort(a + 1 , a + n + 1) ;
    ll l = 0 , r = 1e10 ;
    ll ans = 0 ;
    while(l <= r)
    {
        ll mid = (l + r) / 2 ;
        if(ok(mid))  ans = mid , r = mid - 1 ;
        else  l = mid + 1 ;
    }
    ans = max(ans , base) ;
    cout << ans / 10 << '.' << ans % 10 << '\n' ;
    return 0 ;
}

F. Parentheses

因为串长只有1000,所以可以n^2去做。直接模拟递归的过程,因为递归的底部是(a+b),所以遇到(a+b)就变成a。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int len = 0 , len2 ;
char s[maxn] , t[maxn] ;
int main()
{
    ios ;
    s[len ++] = '(' ;
    while(1)
    {
        char c = getchar() ;
        if(c == ' ')  continue ;
        if(c == '\n')  break ;
        if(isalpha(c))  s[len ++] = 'a' ;
        else if(c == '(' || c == ')')  s[len ++] = c ;
        else  s[len ++] = '+' ;
    } 
    s[len ++] = ')' ;
    bool is_improper = 0 ;
    rep(i , 1 , 1000)
    {
        len2 = 0 ;
        //debug(len) ;
        rep(j , 0 , len - 1)
        {
            //debug(j) ;
            if(j + 2 <= len - 1)
            {
                if(s[j] == '(' && s[j + 1] == 'a' && s[j + 2] == ')' || s[j] == 'a' && s[j + 1] == '+' && s[j + 2] == 'a')
                {
                    j += 2 ;
                    t[len2 ++] = 'a' ;
                    is_improper = 1 ;
                    continue ;
                }
            }
            if(j + 4 <= len - 1)
            {
                if(s[j] == '(' && s[j + 1] == 'a' && s[j + 2] == '+' && s[j + 3] == 'a' && s[j + 4] == ')')
                {
                    j += 4 ;
                    t[len2 ++] = 'a' ;
                    continue ;
                }
            }
            t[len2 ++] = s[j] ;
            //if(i == 2)  debug(11111) , ddebug(s[j] , t[len2 - 1]) ;
        }
        //debug(t[0]) ;
        rep(j , 0 , len2 - 1)  s[j] = t[j] ;
        //debug(s[0]) ;
        len = len2 ;
    }
    //debug(len) ;
    if(len > 1 || len == 1 && s[0] != 'a')  cout << "error\n" ;
    else if(is_improper)  cout << "improper\n" ;
    else  cout << "proper\n" ;
    return 0 ;
}

G. Secret Code

感谢

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-11 ; 
int n ;
struct node
{
    db s , wa , wb , wc ;
    int id ;
    db p ;
    bool operator < (const node &s) const
    {
        if(fabs(p - s.p) > eps)  return p < s.p ;
        else  return id < s.id ;
    }
} a[maxn] ;
void solve(int i)
{
    db s = a[i].s ;
    db wa = a[i].wa ;
    db wb = a[i].wb ;
    db wc = a[i].wc ;
    db res = 0 ;
    res += (s - (wa + wb) / 2) * wa * wb ;
    res += (s - (wb + wc) / 2) * wb * wc ;
    res += (s - (wa + wc) / 2) * wa * wc ;
    res /= s * s * s ;
    a[i].p = res ;
}
int main()
{
    ios ;
    cin >> n ;
    rep(i , 1 , n)  cin >> a[i].s >> a[i].wa >> a[i].wb >> a[i].wc , a[i].id = i ;
    rep(i , 1 , n)  solve(i) ;
    sort(a + 1 , a + n + 1) ;
    // cout << a[1].p << '\n' ;
    // cout << a[2].p << '\n' ;
    rep(i , 1 , n)  cout << a[i].id << " \n"[i == n] ;
    return 0 ;
}

J. Starwars

两个人从军事基地出发,看看能不能在产生字符串相同的情况下分别到达人类控制和非人类控制的行星。反向bfs维护vis[][]。vis[i][j]=1表示可以一个人到达i另一个人到达j。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 1e3 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n , w , c , h , m ;
bool H[maxn] ;
bool M[maxn] ;
vector<pii> g[maxn] ;
bool vis[maxn][maxn] ;
int main()
{
    ios ;
    cin >> n >> w >> c >> h >> m ;
    rep(i , 1 , h)
    {
        int x ;
        cin >> x ;
        x ++ ;
        H[x] = 1 ;
    }  
    rep(i , 1 , m)
    {
        int x ;
        cin >> x ;
        x ++ ;
        M[x] = 1 ;
    }
    rep(i , 1 , w)
    {
        int u , v , w ;
        cin >> u >> w >> v ;
        u ++ , v ++ ;
        g[v].pb({u , w}) ;
    }
    queue<pii> q ;
    rep(i , 1 , n)  rep(j , 1 , n)  if(M[i] && M[j])  q.push({i , j}) , vis[i][j] = 1 ;
    while(!q.empty())
    {
        pii u = q.front() ;
        q.pop() ;
        int x = u.fi ;
        int y = u.se ;
        for(auto s : g[x])  for(auto t : g[y])
        {
            int nxt_x = s.fi ;
            int nxt_y = t.fi ;
            if(!vis[nxt_x][nxt_y] && s.se == t.se)
            {
                vis[nxt_x][nxt_y] = 1 ;
                q.push({nxt_x , nxt_y}) ;
            }
        }
    }
    rep(i , 1 , n)  rep(j , 1 , n)  if(vis[i][j] && H[i] && !H[j])  { cout << "YES\n" ; return 0 ; }
    cout << "NO\n" ;
    return 0 ;
}

K. TV Show Game

3个位置中,一个错误会导致另外两个正确。跑2-sat。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e5 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int n , m ;
int a[5] , b[5] ;
char c[5] ;
vector<int> g[maxn] ;
struct Tarjan
{
    int cnt , scc_num , lay ;
    int low[maxn] , dfn[maxn] , belong[maxn] ; 
    int st[maxn] , s[maxn] ;
    bool vis[maxn] ;
    void init()
    {
        cnt = scc_num = lay = 0 ;
        memset(vis , 0 , sizeof(vis)) ;
        memset(low , 0 , sizeof(low)) ;
    }
    void dfs(int k)
    {
        vis[k] = 1 ;
        low[k] = dfn[k] = ++ lay ;
        st[++ cnt] = k ;
        for(auto v : g[k])
        {
            if(dfn[v] == 0)
            {
                dfs(v) ;
                low[k] = min(low[k] , low[v]) ;
            }
            else if(vis[v])
            low[k] = min(low[k] , dfn[v]) ;
        }
        if(dfn[k] == low[k])
        {
            ++ scc_num ;
            do
            {
                belong[st[cnt]] = scc_num ;
                vis[st[cnt]] = 0 ;
                cnt -- ;
            } while(st[cnt + 1] != k) ;
        }
    }
    void cal()
    {
        for(int i = 1 ; i <= n * 2 ; i ++)  if(dfn[i] == 0)  dfs(i) ;
        rep(i , 1 , n)  if(belong[i] == belong[i + n])  { cout << "-1\n" ; return ; }
        rep(i , 1 , n)  if(belong[i] < belong[i + n])  cout << 'B' ;  else  cout << 'R' ;
        cout << '\n' ;
    }
} tarjan ; 
int main()
{
    ios ;
    cin >> n >> m ;
    rep(i , 1 , m)
    {
        rep(j , 1 , 3)
        {
            cin >> a[j] ;
            cin >> c ;
            if(c[0] == 'B')  b[j] = 0 ;
            else  b[j] = 1 ;
        }
        g[a[1] + (1 - b[1]) * n].pb(a[2] + n * b[2]) ;
        g[a[1] + (1 - b[1]) * n].pb(a[3] + n * b[3]) ;
        g[a[2] + (1 - b[2]) * n].pb(a[1] + n * b[1]) ;
        g[a[2] + (1 - b[2]) * n].pb(a[3] + n * b[3]) ;
        g[a[3] + (1 - b[3]) * n].pb(a[1] + n * b[1]) ;
        g[a[3] + (1 - b[3]) * n].pb(a[2] + n * b[2]) ;
    }
    tarjan.cal() ;
    return 0 ;
}

L. Working Plan

每天优先用剩余工作天数最多的人,这样可以使后面安排更加灵活。有一些细节特判。

#include<bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define sz(x)  (int)x.size()
#define cl(x)  x.clear()
#define all(x)  x.begin() , x.end()
#define rep(i , x , n)  for(int i = x ; i <= n ; i ++)
#define per(i , n , x)  for(int i = n ; i >= x ; i --)
#define mem0(x)  memset(x , 0 , sizeof(x))
#define mem_1(x)  memset(x , -1 , sizeof(x))
#define mem_inf(x)  memset(x , 0x3f , sizeof(x))
#define debug(x)  cerr << #x << " = " << x << '\n'
#define ddebug(x , y)  cerr << #x << " = " << x << "   " << #y << " = " << y << '\n'
#define ios std::ios::sync_with_stdio(false) , cin.tie(0)
using namespace std ;
typedef long long ll ;
typedef long double ld ;
typedef pair<int , int> pii ;
typedef pair<ll , ll> pll ;
typedef double db ;
const int mod = 998244353 ;
const int maxn = 2e3 + 10 ;
const int inf = 0x3f3f3f3f ;
const double eps = 1e-6 ; 
int m , n , w , h ;
priority_queue<pii> q ;
int W[maxn] , d[maxn] ;
vector<int> ans[maxn] ;
int c[maxn] ;
int lst[maxn] ;
bool vis[maxn] ;
int main()
{
    ios ;
    cin >> m >> n >> w >> h ;
    int sum = 0 ;
    rep(i , 1 , m)  cin >> W[i] , lst[i] = -100000 , sum -= W[i] ;
    rep(i , 1 , n)  cin >> d[i] , sum += d[i] ;
    if(sum != 0)
    {
        cout << "-1\n" ;
        return 0 ;
    }
    rep(i , 1 , n)
    {
        rep(j , 1 , m)  if(W[j] > 0 && lst[j] + h < i && !vis[j])  q.push({W[j] , j}) , vis[j] = 1 ;
        c[i] += c[i - 1] ;
        if(c[i] > d[i])
        {
            cout << "-1\n" ;
            return 0 ;
        }
        int res = d[i] - c[i] ;
        while(!q.empty())
        {
            if(res == 0)  break ;
            pii x = q.top() ;
            q.pop() ;
            vis[x.se] = 0 ;
            ans[x.se].pb(i) ;
            lst[x.se] = i + w - 1 ;
            W[x.se] -= w ;
            c[i] ++ ;
            c[i + w] -- ;
            res -- ;
        }
        if(res != 0)
        {
            cout << "-1\n" ;
            return 0 ;
        }
    }
    cout << "1\n" ;
    rep(i , 1 , m)  
    {
        for(auto x : ans[i])  cout << x << ' ' ;
        cout << '\n' ;
    }
    return 0 ;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值