HDU 6364 Ringland

Ringland

题意: 在一个环上有n个男生, n个女生, 现在要求每一个男生与女生配对, 求总代价最小。

题解:

如果2个男生到女生的路交叉了, 那么我们交换这2个男生的路, 总代价是一定会变得小的。

所以组合方式是线性的.

假设有3个男生 3个女生, 并且都已经排好序了。

搭配方式一共有3种。

1 <-> 1 2 <-> 2 3 <-> 3

1 <-> 2 2 <-> 3 3 <-> 1

1 <-> 3 2 <-> 1 3 <-> 2

因为不想要路径交叉, 所以就按照顺序给他们排序配对。

接下来就是顺时针走路和逆时针走的问题了。

先将B 扩展成 3B 减少讨论。

然后对于 a 来说 找到 a - 2/L 的位置 和 a + 1 的位置, 

对 [a - 2/L,  a] 来说 贡献都是 a-b, 对 [a + 1, a + 2/ L] 贡献都是 b-a.

然后对于每一个B也找到进入计算的时间, 出去的时间, 从负变成正的时间,然后搞一下差分就好了。

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
  4 #define LL long long
  5 #define ULL unsigned LL
  6 #define fi first
  7 #define se second
  8 #define pb push_back
  9 #define lson l,m,rt<<1
 10 #define rson m+1,r,rt<<1|1
 11 #define max3(a,b,c) max(a,max(b,c))
 12 #define min3(a,b,c) min(a,min(b,c))
 13 typedef pair<int,int> pll;
 14 const int inf = 0x3f3f3f3f;
 15 const LL INF = 0x3f3f3f3f3f3f3f3f;
 16 const LL mod =  (int)1e9+7;
 17 const int N = 2e6;
 18 LL a[N], b[N];
 19 int l[N], r[N], v[N], in[N], out[N];
 20 LL sum[N];
 21 struct FastIO {
 22     static const int S = 1310720;
 23     int wpos;
 24     char wbuf[S];
 25     FastIO() : wpos(0) { }
 26     inline int xchar() {
 27         static char buf[S];
 28         static int len = 0, pos = 0;
 29         if (pos == len) pos = 0, len = fread(buf, 1, S, stdin);
 30         if (pos == len) return -1;
 31         return buf[pos++];
 32     }
 33     inline int xint() {
 34         int c = xchar(), x = 0, s = 1;
 35         while (c <= 32) c = xchar();
 36         if (c == '-') s = -1, c = xchar();
 37         for (; '0' <= c && c <= '9'; c = xchar()) x = x * 10 + c - '0';
 38         return x * s;
 39     }
 40     ~FastIO() {
 41         if (wpos) fwrite(wbuf, 1, wpos, stdout), wpos = 0;
 42     }
 43 } io;
 44 inline int Find(int x, LL v){
 45     while(b[x] < v) x++;
 46     return x;
 47 }
 48 LL n, L;
 49 void in1(){
 50     n = io.xint();
 51     L = io.xint();
 52     for(int i = 1; i <= n; i++){
 53         a[i] = io.xint();
 54         a[i] += L;
 55     }
 56     for(int i = 1; i <= n; i++)
 57         b[i] = io.xint();
 58 }
 59 void in2(){
 60     scanf("%lld%lld", &n, &L);
 61     for(int i = 1; i <= n; i++){
 62         scanf("%lld", &a[i]);
 63         a[i] += L;
 64     }
 65     for(int i = 1; i <= n; i++)
 66         scanf("%lld", &b[i]);
 67 }
 68 void solve(){
 69     in1();
 70     //in2();
 71     for(int i = 1;i <= 2*n; i++)
 72         b[i+n] = b[i] + L;
 73     for(int i = 1; i <= n; i++){
 74         l[i] = Find(l[i-1], a[i] - L/2);
 75         r[i] = Find(r[i-1], a[i] + 1);
 76     }
 77     int lf = l[1];
 78     memset(sum, 0, sizeof(LL) *(n+1));
 79     for(int i = 1; i <= n; i++) sum[1] += a[i];
 80     for(int i = 1; i <= n; i++){
 81         int t = r[i] - lf + 1;
 82         if(t - i >= 0) sum[t-i+1] -= 2 * a[i];
 83         else sum[1] -= a[i];
 84     }
 85     v[0] = 1;
 86     out[0] = 1;
 87     int j = 1;
 88     for(int i = lf; i <= n*3; i++, j++){
 89         if(j <= n) in[j] = 1;
 90         else in[j] = in[j-1] + 1;
 91         out[j] = out[j-1] + 1;
 92         v[j] = v[j-1];
 93         while(v[j] <= n && a[v[j]] < b[i]) v[j]++;
 94         if(in[j] > n) break;
 95     }
 96     for(int i = 1; i < j; i++){
 97         if(i <= n){
 98             v[i] = i - (v[i]-1) + 1;
 99             if(v[i] < 1) v[i] = 1;
100         }
101         else {
102             if(v[i] == n+1) v[i] = in[i];
103             else v[i] = in[i] + (n - v[i] + 1);
104         }
105     }
106     for(int i = 1, p = lf; i < j; i++, p++){
107         sum[in[i]] -= b[p];
108         if(out[i] <= v[i]) sum[out[i]] += b[p];
109         else {
110             sum[v[i]] += 2 * b[p];
111             sum[out[i]] -= b[p];
112         }
113     }
114     LL ans = INF, tmp = 0;;
115     for(int i = 1; i <= n; i++){
116         tmp += sum[i];
117         ans = min(ans, tmp);
118     }
119     printf("%lld\n", ans);
120 }
121 int main(){
122     int t;
123     scanf("%d", &t);
124     while(t--){
125         solve();
126     }
127     return 0;
128 }
View Code

 

posted @ 2018-08-11 10:09  Schenker  阅读(592)  评论(0编辑  收藏  举报