GDKOI2015 day2

今天又挂了TAT。

得分情况

score
watchdogs    AAWWWWWWWW
planetcup    AAATTTTTTT
v            AAAAAAAAAA
avenger      ATTTTTTTTT

题目在此,希望这个网址不要挂。

watchdogs

大水题,不过读入时错了。TAT。第一题又挂了QAQ。什么时候才能让我A掉第一题送分题?!

planetcup

非常非常水的一道题目,但是我不会做(囧),没有想到可以枚举分界线,只要想到这个就不难了。
我觉得这题的风格非常像rng_58出的神题。Orz。他出的题往往做法看起来很简单,不过就是想不出来。

做法:枚举第一轮的第\(K\)名选手,然后DP即可。

v

大水题。只要知道如何合并路径的信息就非常水了。
不过听说他们每个结点要记很多东西,l神z犇h听说记了\(12\)个Orz。

我记了:

  • 路径长度
  • 左下
  • 右下
  • 左上下
  • 右上下
  • 目前最优答案

avenger

没时间做。直接暴力\(10\)分。z神h犇xOrz。

补充一下解法:
其实这题有很多特殊性,如果我们尝试着去模拟一下小数据,发现序列是有一定的规律的!

不妨把题目中所说的“在\(K\)进制的表示下的最低位都会出现循环变换”表示为操作change。

那么题目的伪代码就可以写成

while X > 0
    p = stack.pop
    change
    if p <= L
        repeat K times
            stack.push(AK + p)
    else
        decrease X

\(L=cAK+d\),其中\(c=\lfloor \frac {L} {AK} \rfloor\)\(d= L \mod (AK)\)
首先,
必须要发现的一点是:栈里的元素\(i\)只可能是——令\(i=pAK+q\),其中\(0\leq p\leq c+1,0 \leq q \leq d\)

然后:
如果栈顶的元素是\(p\),栈顶指针为\(top\)
\(f(p)\)\(top\)变为\(top-1\)需要change的次数。
那么对于任意的\(p\),有\(f(p) \mod K = 1\)

接着:
凭着上面所说的两点,我们可以很(ping)形(gan)象(jue)地画出一个表格:
不妨举个例子\(K = 5, L = 21, A = 2\)
070834501178490.png

结合表格,注意观察\(X=1,2,3,4,...\)时的答案(*符号是为了方便找规律):

30 31 32 33 34 * 31 32 33 34 30 * 22 23 24 * 
31 32 33 34 30 * 22 23 24 * 30 31 32 33 34 *
22 23 24 * 30 31 32 33 34 * 31 32 33 34 30 *
23 24 * 30 31 32 33 34 * 31 32 33 34 30 * 22
24 * 30 31 32 33 34 * 31 32 33 34 30 * 22 23 

31 32 33 34 30 * 22 23 24 * 30 31 32 33 34 *
22 23 24 * 30 31 32 33 34 * 31 32 33 34 30 *
23 24 * 30 31 32 33 34 * 31 32 33 34 30 * 22
24 * 30 31 32 33 34 * 31 32 33 34 30 * 22 23
30 31 32 33 34 * 31 32 33 34 30 * 22 23 24 * 

22 23 24 * 30 31 32 33 34 * 31 32 33 34 30 *
23 24 * 30 31 32 33 34 * 31 32 33 34 30 * 22
24 * 30 31 32 33 34 * 31 32 33 34 30 * 22 23
30 31 32 33 34 * 31 32 33 34 30 * 22 23 24 * 
31 32 33 34 30 * 22 23 24 * 30 31 32 33 34 * 
...

(注意每一行有\((d + 1) K + (K - d - 1)\))个元素。

到了这里,我也不知到应该怎样用语言来描述规律了,囧(我突然感到(zi)了(ji)语(shi)言(ge)的(da)乏(ju)力(ruo)!)。
不过凭着栈的规律变化,并且结合表格(很重要所以我说两遍),我相信你已经知道了该题的解法,这里给个结论,答案的循环节为\(((d + 1) K + (K - d - 1) )K^c\)

上面所说的是第一种情况\(d < K\)

如果是第二种情况\(d \geq k\),就简单多了,例子:不妨举个例子\(K = 5, L = 25, A = 2\)
我们再来结合表格(很重要所以我说三遍),注意观察\(X=1,2,3,4,...\)时的答案:
这里就不画了。答案的循环节为\(K^{c + 2}\)

那应该怎样算答案呢?这里举第一种情况的例子:

  • \(t = (d + 1) K + (K - d - 1)\),把\(X\)拆成\(a_0 + a_1 t + a_2 t K + a_3 t K^2 + a_4 t K^3 ...\),那么我们可以算出答案在哪一行,通过\((\sum_{i=0}{a_i}) \mod K\)
  • 再通过\(a_0\)的值确定是哪一列。

情况二就更简单了。

这样就大功告成了QAQ!

贴个代码(不知道对不对)

#include <cstdio>
#include <iostream>
using namespace std;

typedef unsigned long long i64;

const i64 INF = (i64) 1e19;

i64 myPower(i64 a, i64 b) {
    i64 ret = 1;
    for (i64 i = 0; i < b; i ++) {
        if (INF / a >= ret) 
            ret *= a;
        else return INF;
    }
    return ret;
}

int main() {
    freopen("avenger.in", "r", stdin);
    freopen("avenger.out", "w", stdout);
    int cases; 
    cin >> cases;
    for (int i = 0; i < cases; i ++) {
        i64 X, K, L, A;
        cin >> X >> K >> L >> A;
        i64 AK = A * K;
        i64 C = L / AK;
        i64 D = L - C * AK;
        
        if (D >= K - 1) {
            i64 ans = 0;
            X --;
            X %= myPower(K, C + 2);
            for (; X; X /= K) {
                ans += X % K;
            }
            ans = ans % K + (C + 1) * AK;
            cout << ans << endl;
        }
        else {
            i64 L = D + 1;
            i64 R = K - L;
            
            i64 ans = X % (K * L + R);

            X --;
            X /= K * L + R;
            X %= myPower(K, C);
            i64 start = 0;
            for (; X; X /= K) {
                start += X % K;
            }
            start %= K;

            if (start < L)
                ans += start * K;
            else 
                ans += L * K + (start - L);

            ans %= K * L + R;
            if (ans == 0) ans = K * L + R;

            if (ans <= K * L) {
                cout << ((ans - 1) % K + (ans - 1) / K) % K + AK * (C + 1) << endl;
            }
            else {
                cout << (L + ans - K * L - 1) + AK * C << endl;
            }
        }
    }
    return 0;
}

幸亏gdkoi的成绩不算进gdoi,不然很可能。。。。

转载于:https://www.cnblogs.com/wangck/p/4307522.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值