[CSP-S模拟测试]:天才绅士少女助手克里斯蒂娜(数学+树状数组)

题目描述

  红莉栖想要弄清楚楼下天王寺大叔的显像管电视对“电话微波炉(暂定)”的影响。
  选取显像管的任意一个平面,一开始平面内有个$n$电子,初始速度分别为$v_i$,定义飘升系数为
$$\sum \limits_{1\leqslant i<j\leqslant n}|v_i\times v_j|^2$$
  由于电视会遭到大叔不同程度的暴击,电子的速度常常会发生变化。也就是说,有两种类型的操作:
  $\bullet 1\ p\ x\ y$将$v_p$改为$(x,y)$
  $\bullet 2\ l\ r$询问$[l,r]$这段区间内的电子的飘升系数
  这么简单的问题红莉栖当然能解决,但是她需要一个人帮忙验证一下结果的正确性。
  由于唯一帮得上忙的桶子去找菲利斯了,于是只能拜托你来完成这个任务了。答案对$20170927$取模即可。


输入格式

第一行两个整数$n,m$表示电子个数和询问个数。
接下来$n$行,每行两个整数$x,y$表示$v_i$。
接下来$m$行,每行形如$1\ p\ x\ y$或$2\ l\ r$,分别表示两种操作。


输出格式

对于每个操作$2$,输出一行一个整数表示飘升系数对$20170927$取模的值。


样例

样例输入:

9 5
13052925 5757314
9968857 11135327
13860145 3869873
6912189 3461377
2911603 7061332
6334922 7708411
5505379 5915686
6806727 588727
7603043 15687404
2 1 6
1 7 2602783 18398476
1 8 8636316 19923037
2 2 7
2 2 4

样例输出:

18529202
963126
19167545


数据范围与提示

对于$100\%$的数据,$1\leqslant n,m\leqslant 10^6,0\leqslant x_i,y_i<20170927,1\leqslant l_i\leqslant r_i\leqslant n$。


题解

我依($qing$)稀($chu$)记得波波老师让我出过这道题的数据,就是题面动了一点,时间限制调小了(当时我还是挺慌的,原题$4s$,现在这个时限我的代码都跑不过我的数据……),但是我还是打了,然后它就$A$了……

简单说一下,上面那个鬼畜的$\times$其实是叉积也就是:

$v_1=(x_1,y_1),v_2=(x_2,y_2) \Rightarrow \vec{v_1}\times \vec{v_2}=x_1\times y_2-x_2\times y_1$。

初步是这样的:$\large \begin{array}{ll} ans &=& \sum \limits_{i=l}^r \sum \limits_{j=i+1}^r (v_i \times v_j)^2 \\ &=& \sum \limits_{i=l}^r \sum \limits_{j=i+1}^r (x_iy_j-x_jy_i)^2 \end{array}$

那么我们化简一下上面那个式子即可得到:

$\large \begin{array}{ll} ans &=& \sum \limits_{i=l}^{r} \sum \limits_{j=i+1}^r (x_i^2y_j^2+x_j^2y_i^2-2x_iy_ix_jy_j) \\ &=& \sum \limits_{i=l}^r \sum \limits_{j=i+1}^r x_i^2y_j^2 + \sum \limits_{i=l}^r \sum \limits_{j=i+1}^r x_j^2y_i^2 - \sum \limits_{i=l}^r \sum \limits_{j=i+1}^r 2x_iy_ix_jy_j \\ &=& \sum \limits_{i=l}^r \sum \limits_{j=l}^r [i!=j]\times x_i^2y_j^2 - \sum \limits_{i=l}^r \sum \limits_{j=l}^r [i!=j]\times x_iy_ix_jy_j \\ &=& \sum \limits_{i=l}^r x_i^2 (\sum \limits_{j=l}^r y_j^2 -y_i^2) - (\sum \limits_{i=l}^r x_iy_i (\sum \limits_{j=l}^r x_jy_j - x_iy_i)) \\ &=& \sum \limits_{i=l}^r x_i^2 \sum \limits_{j=l}^r y_j^2 - \sum \limits_{i=l}^r x_i^2y_i^2 - (\sum \limits_{i=l}^r x_iy_i \sum \limits_{j=l}^r x_jy_j - \sum \limits_{i=l}^r x_i^2 y_i^2) \\ &=& \sum \limits_{i=l}^r x_i^2\times \sum \limits_{i=l}^ry_i^2 - (\sum \limits_{i=l}^r x_iy_i)^2\end{array}$

有了这个式子,我们就可以用三个树状数组维护分别维护$\sum \limits_{i=l}^r x_i^2$,$\sum \limits_{i=l}^r y_i^2$,$\sum \limits_{i=l}^r x_iy_i$即可。

时间复杂度:$\Theta((n+m)\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
const int mod=20170927;
int n,m;
long long tr[3][4000001];
pair<long long,long long> e[1000001];
void add(int x,long long val,int id)
{
	for(int i=x;i<=n;i+=i&-i)
		tr[id][i]=(tr[id][i]+val)%mod;
}
long long query(int x,int id)
{
	long long res=0;
	for(int i=x;i;i-=i&-i)
		res=(res+tr[id][i])%mod;
	return res;
}
long long ask(int l,int r,int id)
{
	return (query(r,id)-query(l-1,id)+mod)%mod;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&e[i].first,&e[i].second);
		add(i,e[i].first*e[i].first,0);
		add(i,e[i].second*e[i].second,1);
		add(i,e[i].first*e[i].second,2);
	}
	while(m--)
	{
		int op;
		scanf("%d",&op);
		if(op==1)
		{
			int p;
			long long x,y;
			scanf("%d%lld%lld",&p,&x,&y);
			add(p,(x*x%mod-e[p].first*e[p].first%mod+mod)%mod,0);
			add(p,(y*y%mod-e[p].second*e[p].second%mod+mod)%mod,1);
			add(p,(x*y%mod-e[p].first*e[p].second%mod+mod)%mod,2);
			e[p]=make_pair(x,y);
		}
		else
		{
			int l,r;
			scanf("%d%d",&l,&r);
			long long res=ask(l,r,0)*ask(l,r,1)%mod,res1=ask(l,r,2);
			res=(res-(res1*res1%mod)+mod)%mod;
			printf("%lld\n",res);
		}
	}
	return 0;
}


rp++

原文地址:https://www.cnblogs.com/wzc521/p/11625031.html

时间: 2024-10-12 07:27:50

[CSP-S模拟测试]:天才绅士少女助手克里斯蒂娜(数学+树状数组)的相关文章

csps-s模拟测试60嘟嘟噜,天才绅士少女助手克里斯蒂娜,凤凰院凶真题解

题面:https://www.cnblogs.com/Juve/articles/11625190.html 嘟嘟噜: 约瑟夫问题 第一种递归的容易re,但复杂度较有保证 第二种适用与n大于m的情况 第三种O(n)用于n不太大或m大于n时 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define int lon

10.5「嘟嘟噜」&#183;「天才绅士少女助手克里斯蒂娜」&#183;「凤凰院凶真」

又是一部番???? A. 嘟嘟噜 以为是个神仙题,就只打了个约瑟夫问题,然后QJ了M==2的分, 事实上因为M很小,可以让让轮数跳转,瞎算算就出来了. B. 天才绅士少女助手克里斯蒂娜 考试一开始看错题了,样例过不了异常崩溃........ 1h过去了,我读错题了(一脸震惊) 然后...好像是线段树,但不会维护....... 好像式子能拆开,wc这怎么维护??? after 10min 好像可以维护了... C. 凤凰院凶真 没时间想了,事实上是一个裸的最长公共上升子序列 考虑DP,f[i][j

[CSP-S模拟测试]:小P的单调数列(树状数组+DP)

题目描述 小$P$最近喜欢上了单调数列,他觉得单调的数列具有非常多优美的性质.经过小$P$复杂的数学推导,他计算出了一个单调增数列的艺术价值等于该数列中所有书的总和.并且以这个为基础,小$P$还可以求出任意一个数列的艺术价值,它等于将这个数列顺次划分若干个极长单调区间(相邻两个单调区间的单调性必须不相同)后,每个单调区间中元素总和的平均值.比如对于数列$3\ 7\ 9\ 2\ 4\ 5$,它将被划分为$[3\ 7\ 9]\ [2]\ [4\ 5]$,其艺术价值为$\frac{19+2+9}{3}

[CSP-S模拟测试]:Equation(数学+树状数组)

题目描述 有一棵$n$个点的以$1$为根的树,以及$n$个整数变量$x_i$.树上$i$的父亲是$f_i$,每条边$(i,f_i)$有一个权值$w_i$,表示一个方程$x_i+x_{f_i}=w_i$,这$n−1$个方程构成了一个方程组.现在给出$q$个操作,有两种类型:$\bullet 1\ u\ v\ s$,表示询问加上$x_u+x_v=s$这个方程后,整个方程组的解的情况.具体来说,如果方程有唯一解,输出此时$x_1$的值:如果有无限多个解,输出$inf$:如果无解,输出$none$.注意

Hdu 3887树状数组+模拟栈

题目链接 Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1757    Accepted Submission(s): 582 Problem Description You are given a tree, it’s root is p, and the node is numbered fr

Codeforces 216D Spider&#39;s Web 树状数组+模拟

题目链接:http://codeforces.com/problemset/problem/216/D 题意: 对于一个梯形区域,如果梯形左边的点数!=梯形右边的点数,那么这个梯形为红色,否则为绿色, 问: 给定的蜘蛛网中有多少个红色. 2个树状数组维护2个线段.然后暴力模拟一下,因为点数很多但需要用到的线段树只有3条,所以类似滚动数组的思想优化内存. #include<stdio.h> #include<iostream> #include<string.h> #in

PAT甲题题解-1095. Cars on Campus(30)-(map+树状数组,或者模拟)

题意:给出n个车辆进出校园的记录,以及k个时间点,让你回答每个时间点校园内的车辆数,最后输出在校园内停留的总时间最长的车牌号和停留时间,如果不止一个,车牌号按字典序输出. 几个注意点: 1.如果一个车连续多次进入,只取最后一个 2.如果一个车连续多次出去,只取第一个 3.一个车可能出入校园内好几次,停留时间取总和 实际上题目就是让我们求某个时间段内的车辆总和,时间段其实就相当于一个区间,区间求和的话,很快就联想到树状数组和线段树.然而怎么将时间段和区间联系起来呢,那就存储出现在记录和询问里的所有

Codeforces 12D Ball 树状数组模拟3个元素的排序

题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h> #include<queue> #include<string> #include<stdlib.h> #include<a

Uva - 1513 Moive collection ( 模拟栈 + 树状数组基本操作 )

Uva - 1513 Moive collection ( 模拟栈 + 树状数组基本操作 ) 题意: 一个书架,原来所有的书都是按顺序摆好的,书的编号从1开始到n 操作: 取出一本书,统计在这本书之前有多少本书,统计完之后,将这本书放在书架的第一位. 如:  1 2 3 4 5取4   4 1 2 3 5 (取之前,有3本书在4前面,取完后,将4放在栈顶)取4   4 1 2 3 5 (取之前,有0本书在4前面,取完后,将4放在栈顶)取2   2 4 1 3 5 (取之前,有2本书在2前面,取完