【Solve summary】求和

【Problem description】

问题描述

一条狭长的纸带被均匀划分出了n个格子,格子编号从1到n。每个格子上都染了一种颜色color_i(用[1,m]当中的一个整数表示),并且写了一个数字number_i。

  定义一种特殊的三元组:(x,y,z),其中x,y,z都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:
  xyz是整数,x<y<z,y-x=z-y colorx=colorz  

满足上述条件的三元组的分数规定为(x+z)*(number_x+number_z)。整个纸带的分数规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以10,007所得的余数即可。

【Input format】

第一行是用一个空格隔开的两个正整数n和m,n表纸带上格子的个数,m表纸带上颜色的种类数。
  第二行有n用空格隔开的正整数,第i数字number表纸带上编号为i格子上面写的数字。
  第三行有n用空格隔开的正整数,第i数字color表纸带上编号为i格子染的颜色。

【Output format】

共一行,一个整数,表示所求的纸带分数除以10,007所得的余数。

【Algorithm design】

Simple enumeration + Mathematics deal

【Problem analysis】

Consequent不可取

Mathematics思维

核心:数据分离

N太大 直接搞O(N2)

读题

x<y<z,y-x=z-y,colorx=colorz
翻译一下

x,z奇偶性相同且同种颜色

那么把n拆成两条链

奇数链

偶数链

两链互不相干

对于链上所有同种颜色的点 都可以求分数

既然如此再看

(x+z)*(number_x+number_z)

拆解后

x*num_x+z*num_z+x*num_z+z*num_x

前缀和思想

取一点x 那么关于x的所有三元组的分数之和

x*num_x*cnt_others + sumcnt_others + x*numcnt_others + num_x*idcnt_others

所以只需要分两条链

枚举每个点

根据其颜色进行处理

O(2n)

Anyway

把cnt处理完了再搞会有一倍冗出

所以边枚举边搞最好

先前忘了这点愣了几分钟

错误记录

没把ans求余

没考虑sum也很大也要求余

即使执行上述操作 sum还是很大

LL型适配

【Source code】

#include <bits/stdc++.h>

#define F(i,j,k) for(int i=j;i<=k;i++)

#define D(i,j,k) for(int i=j;i>=k;i--)

#define sc(i) scanf("%lld",&i)

#define mo 10007

#define ll long long

#define R return

using namespace std;

int n,m;

ll ans,num[100010],col[100010],sumnu[100010],sum[100010],sumid[100010],cnt[100010];

void read()

{

cin>>n>>m;

F(i,1,n)sc(num[i]);

F(i,1,n)sc(col[i]);

R;

}

void work()

{

F(jff,1,2)

{

memset(sumid,0,sizeof(sumid));

memset(sumnu,0,sizeof(sumnu));

memset(sum,0,sizeof(sum));

memset(cnt,0,sizeof(cnt));

for(int i=jff;i<=n;i+=2)

{

ans=(ans+sum[col[i]]+num[i]*i*cnt[col[i]])%mo;

ans=(ans+sumnu[col[i]]*i)%mo;

ans=(ans+sumid[col[i]]*num[i])%mo;

sumid[col[i]]=(sumid[col[i]]+i)%mo;

sumnu[col[i]]=(sumnu[col[i]]+num[i])%mo;

sum[col[i]]=(sum[col[i]]+num[i]*i)%mo;

cnt[col[i]]++;

}

}

cout<<ans<<endl;

R;

}

int main()

{

freopen("sum.in","r",stdin);

freopen("sum.out","w",stdout);

read();

work();

R 0;

}

原文地址:https://www.cnblogs.com/qswx/p/9155674.html

时间: 2024-10-11 16:09:18

【Solve summary】求和的相关文章

Castle 整合.NET Remoting

今天研究了一下Castle的Remoting Facility.记录如下: 微软以前使用COM/DCOM的技术来处理分布式系统架构,通过Client端的Proxy代理程序来呼叫远程Server机器上的对象..NET Framework则使用.NET Remoting或Web Services技术来实作分布式处理的工作概念:在这里针对.NET Remoting的设计架构做一个初步的简介和Castle整合示例. .NET Framework提供了多种的机制来支持Remoting,如: .利用Chan

c# ref与out的区别

相同点:都是输出参数 不同点: ref: 1.必须初始化,即:必须赋初始值: 2.有进有出: 3.用在需要被调用的方法修改调用者的引用的时候. 4.是传递参数的地址 out: 1.不需要初始化,即:不需要赋初始值: 2.只出不进: 3.用在需要retrun多个返回值的地方: 4.返回值: 通过代码更直观的看出它们的区别: class Program { static void Main(string[] args) { //num1,num2,必须赋值 int num1 = 10; int nu

6.17 类思想的简单学习, 以及 封装

------program.cs-------- using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 封装 { class Program { static void Main(string[] args) { student s = new student();//实例化 teacher t =

集合类 Contains 方法 深入详解 与接口的实例

.Net 相等性:集合类 Contains 方法 深入详解 http://www.cnblogs.com/ldp615/archive/2009/09/05/1560791.html 1.接口的概念及声明接口是一种用来定义程序的协议,它描述可属于任何类或结构的一组相关行为.接口可有方法.属性.事件和索引器或这四种成员的任何组合类型,但不能包含字段.那么接口具有哪些特点呢?·接口类似于抽象基类:继承接口的任何非抽象类型都必须实现接口的所有成员(说明:如类A继承接口B,那么A中必须实现B中定义的属性

Enumerable扩展方法

/// <summary> /// The i enumerable extension. /// </summary> public static class IEnumerableExtension { #region Join /// <summary> /// 根据字符串拆分数组 /// </summary> /// <param name="source"> /// 要拆分的数组 /// </param>

C# 委托, 铭轩同学原创

委托的定义: (1) 将方法作为变量使用的一种机制,就是将方法当作变量用(声明,赋值,传参)   (2) 将变量当作方法来用,首先就要去声明变量,就要考虑变量的类型,就是(委托变量,对应方法的返回值,参数等),顾名思义:委托就是委托别人去干某些事情,下面是一个实例方法的实现 例如:我现在饿了,但是我很懒,就是不想出去买,所以这时候我可以委托室友帮我带一份,这样我就已经实现委托了 class Program { //声明一个委托 delegate int DelegateCompare(objec

EF Core中执行Sql语句查询操作之FromSql,ExecuteSqlCommand,SqlQuery

一.目前EF Core的版本为V2.1 相比较EF Core v1.0 目前已经增加了不少功能. EF Core除了常用的增删改模型操作,Sql语句在不少项目中是不能避免的. 在EF Core中上下文,可以返货DbConnection ,执行sql语句.这是最底层的操作方式,代码写起来还是挺多的. 初次之外 EF Core中还支持 FromSql,ExecuteSqlCommand 连个方法,用于更方便的执行Sql语句. 另外,目前版本的EF Core 不支持SqlQuery,但是我们可以自己扩

【树状数组区间修改区间求和】codevs 1082 线段树练习 3

http://codevs.cn/problem/1082/ [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int maxn=2e5+2; 5 int n; 6 ll a[maxn]; 7 ll c1[maxn]; 8 ll c2[maxn]; 9 int lowbit(int x) 10 { 11 return x&-x; 12 } 13 void add(l

POJ 3233 Matrix Power Series 矩阵快速幂+二分求和

矩阵快速幂,请参照模板 http://www.cnblogs.com/pach/p/5978475.html 直接sum=A+A2+A3...+Ak这样累加肯定会超时,但是 sum=A+A2+...+Ak/2+A(k/2)*(A+A2+...+Ak/2)    k为偶数时: sum=A+A2+...+A(k-1)/2+A((k-1)/2)*(A+A2+...+A(k-1)/2)+Ak    k为奇数时. 然后递归二分求和 PS:刚开始mat定义的是__int64,于是贡献了n次TLE... #i