• 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} floor)(d= L mod (AK))
    首先,
    必须要发现的一点是:栈里的元素(i)只可能是——令(i=pAK+q),其中(0leq pleq 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)

    结合表格,注意观察(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,不然很可能。。。。

  • 相关阅读:
    15第十四章:Docker轻量级可视化工具Portainer
    14第十三章:Dockercompose容器编排
    01第一章:【01】设计模式前言
    16第十五章:Docker容器监控
    13第十二章:Docker网络
    00设计模式【目录】
    03第一章:【02】单一职责原则(SRP)
    12第十一章:Docker微服务实战
    02第一章:【01】设计模式七大原则
    node2vec: Scalable Feature Learning for Networks
  • 原文地址:https://www.cnblogs.com/wangck/p/4307522.html
Copyright © 2020-2023  润新知