题目名称 2611. [HZOI 2016]你猜是不是DP V2
输入输出 NC.in/out
难度等级 ★★☆
时间限制 500 ms (0.5 s)
内存限制 128 MiB
测试数据 18
题目来源 Gravatar_Itachi 于2017-02-15加入
开放分组 全部用户
提交状态
分类标签
分享题解
通过:4, 提交:35, 通过率:11.43%
GravatarYGOI_真神名曰驴蛋蛋 100 3.593 s 126.72 MiB C++
GravatarYGOI_真神名曰驴蛋蛋 100 3.677 s 126.72 MiB C++
GravatarYGOI_真神名曰驴蛋蛋 100 3.836 s 126.59 MiB C++
GravatarYGOI_真神名曰驴蛋蛋 100 3.956 s 126.72 MiB C++
GravatarYGOI_真神名曰驴蛋蛋 83 4.308 s 126.72 MiB C++
GravatarYGOI_真神名曰驴蛋蛋 83 19.651 s 126.46 MiB C++
GravatarAntiLeaf 83 20.121 s 126.46 MiB C++
Gravatar_Itachi 83 20.313 s 98.53 MiB C++
GravatarAntiLeaf 72 25.751 s 127.29 MiB C++
Gravatar_Itachi 66 1.428 s 63.37 MiB C++
关于 你猜是不是DP V2 的近10条评论(全部评论)
回复 :
[size=0][/size]
[size=0]出题人的**卡常妓巧被碾压
还谎称开了5倍时限
[/size]
只有聪明的人才能看见我说了什么
GravatarAntiLeaf
2017-02-26 11:02 12楼
GravatarAntiLeaf
2017-02-26 10:55 11楼
**[size=50]*[/size]
Gravatar可以的.
2017-02-24 16:38 10楼
看着就觉得出题人是个智障
Gravatarriteme
2017-02-24 14:50 9楼
回复:@可以的 :
*[size=50]*[/size][size=100]*[/size]
GravatarGo灬Fire
2017-02-22 13:52 8楼
[size=33]把出题人婊起来
出题人的卡常妓巧被碾压
还谎称开了5倍时限[/size]
Gravatar‎MistyEye
2017-02-19 17:05 7楼
[size=60]↑[/size]这是个沙茶
这题原来没开1.5倍时限,被我碾压后他就谎称开了5倍时限
注意这里你要开
[size=60]
最原本算法的
1.5倍时限
[/size]
GravatarYGOI_真神名曰驴蛋蛋
2017-02-19 16:58 6楼
谨以此题纪念我们的WC2017
本题是对WC2017的T2的继承(和发扬?),所以请大家不要裱我,要裱就裱wys!
UPD:感谢驴蛋蛋,为我提供了一个更好的优化方法,使得标称速度提高了4倍左右,由于原时限没有改,所以现在我可以骄傲地说:
我开了[size=50]5倍时限![/size]
题解如下:
这就是一个模拟,但需要优化时间和空间(是不是像极了WC2017_T2呢?)
关于时间的优化,你需要完成一些基于CPU性能的程序底层优化,如:数组下标访问的连续性。具体详见WC2017某松同学的论文+机智的驴蛋蛋。
关于空间的优化,考虑到膜数最大为61,61+61=122<128,所以我们可以用char数组来存储DP数组,这样就可以把内存开销最大的东西一下子降到1/4.
Gravatar_Itachi
2017-02-19 16:54 5楼
回复 @_Itachi :
珍爱生命,远离某松
GravatarAntiLeaf
2017-02-16 06:11 4楼
回复 @AntiLeaf :
珍爱生命,远离卡常出题人
Gravatar‎MistyEye
2017-02-16 06:03 3楼

2611. [HZOI 2016]你猜是不是DP V2

★★☆   输入文件:NC.in   输出文件:NC.out   简单对比
时间限制:0.5 s   内存限制:128 MiB

【题目描述】


小绿帽同学在做了“2587. [HZOI 2015]你猜是不是DP”后发现自己学会了DP的正确姿势,

于是它非常开心的点开了一道新的题,并且它成功的列出了DP的方程!!

然而那道题的正解是O(nlogn^3)的(小绿帽怎么可能会~),但是小绿帽却列出了n^2的DP方程。

所以还是请你帮助小绿帽同学完成这道题。


下面是小绿帽同学的DP方程:


for(int i=1;i<=n;i++)

    for(int j=1;j<=n;j++)

        f[i][j]=get(f[i-1][j]);

for(int i=1;i<=n;i++)

    for(int j=1;j<=n;j++) {

        f[i][j]+=f[get(f[i-1][j])][get(f[i-1][j]+1)];

        ans+=f[i][j];

    }


其中f[0][1...n]的值由输入给出,ans%p的值即为答案。

其中get()函数是这个样子滴~


int get(int x) {

   x%=p;

   return (x^(x>>7)^(x<<3)^(x>>2))%n+1;

}


你可以认为这个方程就是对的,那么接下来交给你了,帮助小绿帽小朋友解决这个DP问题吧!


【输入格式】


第一行两个整数n,p

第二行n个整数表示f[0][1...n]


【输出格式】

一个整数ans.

【样例输入】

5 2

1 2 3 4 5

【样例输出】

0

【提示】


共18个测试点。

第1~5个测试点每个4分,n<=2000;

第6~13个测试点每个5分,n<=8000;

第14~18个测试点每个8分,n<=11500;

对于第i个测试点,p为第i个素数。

对于18个测试点,n均为4的倍数。

【来源】

一只名字很长的蒟蒻