Luogu 2671 求和 NOIP2015T3
题解
20pts
$O(n^3)$枚举$x,y,z$,根据题目要求判断
40pts
$O(n^2)$枚举$x,z$,需要满足$x,z$奇偶相同
20~40pts的代码我都没有写过...就不贴了
70~90pts
尝试对40pts的暴力进行优化
题目对三元组的两个限制我们在40pts的时候已经用来优化过了,还有一个限制是颜色相同
我们可以以颜色为关键字对数组进行排序,对每个数算答案的时候,只需要枚举相同颜色的这一段即可(因为三元组要求有序,所以要从$x+2$开始枚举)
这样的复杂度是$O(n*cnt_{col})$(这里的$cnt_{col}$为出现次数最多的颜色的出现次数)
使用$scanf$将会得到70pts
使用快读或$scanf+O2$将会得到80pts
使用快读+$O2$将会得到90pts
($fread$在这里的效果和快读是差不多的,因为数只有$1e5$个)
#include <bits/stdc++.h> #define ll long long
#define inf 0x3f3f3f3f
#define il inline namespace io { #define in(a) a=read()
#define out(a) write(a)
#define outn(a) out(a),putchar('\n') #define I_int int
inline I_int read() {
I_int x = , f = ; char c = getchar() ;
while( c < '' || c > '' ) { if( c == '-' ) f = - ; c = getchar() ; }
while( c >= '' && c <= '' ) { x = x * + c - '' ; c = getchar() ; }
return x * f ;
}
char F[ ] ;
inline void write( I_int x ) {
I_int tmp = x > ? x : -x ;
if( x < ) putchar( '-' ) ;
int cnt = ;
while( tmp > ) {
F[ cnt ++ ] = tmp % + '' ;
tmp /= ;
}
while( cnt > ) putchar( F[ -- cnt ] ) ;
}
#undef I_int }
using namespace io ; using namespace std ; #define N 100010
const int mod = ; int n = read() , m = read() ;
struct node {
int col , val , id ;
} a[ N ] ; bool cmp( node a , node b ) {
return a.col < b.col ;
} int main() {
for( int i = ; i <= n ; i ++ ) a[ i ].val = read() , a[ i ].id = i ;
for( int i = ; i <= n ; i ++ ) a[ i ].col = read() ;
sort( a + , a + n + , cmp ) ;
int cur = ;
ll ans = ;
for( int i = ; i <= n ; i ++ ) {
ll sum = ;
for( cur = i + ; a[ i ].col == a[ cur ].col && cur <= n ; cur ++ ) {
if( ( a[ i ].id + a[ cur ].id ) % == )
sum = ( sum + ( 1ll * ( a[ i ].id + a[ cur ].id ) % mod * 1ll * ( a[ i ].val + a[ cur ].val ) % mod ) % mod ) % mod ;
}
ans = ( ans + sum ) % mod ;
}
printf( "%lld\n" , ( ans + mod ) % mod ) ;
return ;
}
100pts
考虑使用数学方法优化以上做法
我们现在有什么条件呢,列举一下
1.$x$和$z$的奇偶性相同且颜色相同
2.求和公式为$(x+z)(num_x+num_z)$
从求和公式入手,把括号拆掉,式子变成$x*num_x+x*num_z+z*num_x+z*num_z$
设$x1,x2,x3$的奇偶性相同且颜色相同(那么他们组成的二元组就等同于符合条件的三元组)
考虑$x1$对答案的贡献:
对于$(x1,x2)$,$x1$的贡献为$x1*num_{x1}+x1*num_{x2}$
对于$(x1,x3)$,$x1$的贡献为$x1*num_{x1}+x1*num_{x3}$
那么$x_1$对答案的贡献就是
$x1*(num_{x2}+num_{x3})+2*x1*num_{x1}$
然后多加入一个数$x4$也可以得到类似的贡献(多代几个也就看出来规律了)
推广到$x_n$结论也是一样的
结论:
设$s=\sum num_{xi}$(这里的$xi$均满足条件1)$cnt=cnt_{col}$,$cnt_{col}$为当前颜色奇偶相同的数的个数
则$xi$对答案的贡献为$xi*(s-num_{xi})+(cnt-1)*xi*num_{xi}$($cnt$要$-1$,因为$xi$不能和自己组成二元组)
所以将$s$和$cnt$统计出来就行了,注意要分奇偶统计
复杂度$O(n)$
#include <bits/stdc++.h> #define ll long long
#define inf 0x3f3f3f3f
#define il inline
#define int long long namespace io { #define in(a) a=read()
#define out(a) write(a)
#define outn(a) out(a),putchar('\n') #define I_int int
inline I_int read() {
I_int x = , f = ; char c = getchar() ;
while( c < '' || c > '' ) { if( c == '-' ) f = - ; c = getchar() ; }
while( c >= '' && c <= '' ) { x = x * + c - '' ; c = getchar() ; }
return x * f ;
}
char F[ ] ;
inline void write( I_int x ) {
if( x == ) { putchar( '' ) ; return ; }
I_int tmp = x > ? x : -x ;
if( x < ) putchar( '-' ) ;
int cnt = ;
while( tmp > ) {
F[ cnt ++ ] = tmp % + '' ;
tmp /= ;
}
while( cnt > ) putchar( F[ -- cnt ] ) ;
}
#undef I_int }
using namespace io ; using namespace std ; #define N 100010
const int mod = ; int n , m ;
struct node {
int col , val ;
} a[ N ] ;
int cnt[ N ][ ] , sum[ N ][ ] ; signed main() {
n = read() , m = read() ;
for( int i = ; i <= n ; i ++ ) a[ i ].val = read() ;
for( int i = ; i <= n ; i ++ ) a[ i ].col = read() ;
for( int i = ; i <= n ; i ++ ) {
cnt[ a[ i ].col ][ i& ] ++ ;
sum[ a[ i ].col ][ i& ] = ( sum[ a[ i ].col ][ i& ] + a[ i ].val ) % mod ;
}
ll ans = ;
for( int i = ; i <= n ; i ++ ) {
ll num = cnt[ a[ i ].col ][ i& ] , s = sum[ a[ i ].col ][ i& ] ;
ans = ( ans + ( i*(s-a[i].val) + (num-)*a[i].val*i ) % mod ) % mod ;
}
printf( "%lld\n" , ans % mod ) ;
return ;
}
Luogu 2671 求和 NOIP2015T3的更多相关文章
- luogu 4427 求和
bjoi 2018 求和 唯一一道可能切的题一个数组还没开long long就成0分了 题目大意: 一棵有根树,并且希望多次询问这棵树上一段路径上所有节点深度的k次方和,而且每次的k可能是不同的 此处 ...
- [洛谷2671]求和<前缀和&模拟>
题目链接:https://www.luogu.org/problemnew/show/P2671 这是noip2015普及组的第三题,谁说的普及组的题就一定水的不行,这道题就比较有意思的 这道题的暴力 ...
- Luogu P1625 求和
题意 给定两个整数 \(n,m\),求 \[\sum\limits_{i=1}^{n}\frac{1}{\prod\limits_{j=i}^{i+m-1}j} \] \(\texttt{Data R ...
- luogu P1630 求和(枚举暴力)
题意 题解 可以发现当a=10001时, 和1是等价的. 所以这题就水了. #include<iostream> #include<cstring> #include<c ...
- [Luogu] 余数求和
question: $$\sum_{i=1}^{n} k \bmod i$$$$\sum_{i=1}^{n} k - \lfloor \frac{k}{i} \rfloor i$$$$\sum_{i= ...
- [Luogu 2261] CQOI2007 余数求和
[Luogu 2261] CQOI2007 余数求和 这一定是我迄今为止见过最短小精悍的省选题了,核心代码 \(4\) 行,总代码 \(12\) 行,堪比小凯的疑惑啊. 这题一看暴力很好打,然而 \( ...
- BZOJ 4555 Luogu P4091 [HEOI2016/TJOI2016]求和 (第二类斯特林数)
题目链接 (luogu) https://www.luogu.org/problem/P4091 (bzoj) https://www.lydsy.com/JudgeOnline/problem.ph ...
- [Luogu P2261] [CQOI2007]余数求和 (取模计算)
题面 传送门:https://www.luogu.org/problemnew/show/P2261 Solution 这题显然有一个O(n)的直接计算法,60分到手. 接下来我们就可以拿出草稿纸推一 ...
- 【Bzoj4555】【Luogu P4091】求和(NTT)
题面 Bzoj Luogu 题解 先来颓柿子 $$ \sum_{i=0}^n\sum_{j=0}^iS(i,j)2^jj! \\ =\sum_{j=0}^n2^jj!\sum_{i=0}^nS(i,j ...
随机推荐
- Python装饰器与面向切面编程(转)
add by zhj: 装饰器的作用是将代码中可以独立的功能独立出来,实现代码复用,下面那个用于统计函数运行时间的装饰器就是很好的例子,我们不用修改原有的函数和调用原有函数的地方,这遵循了开闭原则.装 ...
- mysql transaction 事务
1.事务简介 一个"最小的"不可再分的"工作单元". 一个事务通常对应了一个完整的业务.如:银行的转账功能,a转账给b,a扣钱,b加钱. 一个事务包含一条或多条 ...
- InnoDB: Operating system error number 87 in a file operation. 错误87的解决方法
InnoDB: Operating system error number 87 in a file operation. 错误87的解决方法 140628 8:10:48 [Note] Plugi ...
- ASCII对照表
ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 ASCII值 控制字符 0 NUT 32 (space) 64 @ 96 . 1 SOH 33 ! 65 A 97 a 2 ST ...
- col-md-*和col-sm-*
屏幕大于(≥992px) ,使用col-md-* 而不是col-sm-*如果屏幕大于(≥768px),小雨<=992px,使用col-sm-* 而不是col-md-*
- 爆出的法拉第未来(Faraday Future,以下简称“FF”)
在本次融资"乌龙"之前,FF已经传出过两次融资消息,传闻对象既有印度大型财团,也是捷豹路虎的控股方塔塔集团,也有香港李嘉诚之子"小巨人"李泽楷,但最后都被各方否 ...
- Summary: Java中函数参数的传递
函数调用参数传递类型(java)的用法介绍. java方法中传值和传引用的问题是个基本问题,但是也有很多人一时弄不清. (一)基本数据类型:传值,方法不会改变实参的值. public class Te ...
- uva10905
/* 很好的字符串 比较方法 很多个字符串 组成的 数字 需要最大 然后 比较 a和b 是 比较a+b 和b+a 的大小 */ #include<cstdio> #include<s ...
- quartz-job实现定时任务配置
使用quartz开源调度框架,写服务实现在一些指定场景发送特定短信,创建一个实现org.quartz.Job接口的java类.Job接口包含唯一的方法: public void execute(Job ...
- linux rsync同步工具
linux rsync同步工具 1.rsync介绍rsync是一款开源的.快速的.多功能的.可实现全量及增量的本地或远程数据同步备份的优秀工具.rsync软件适用于unix/linux/windows ...