天才绅士少女助手克里斯蒂娜 解题报告

天才绅士少女助手克里斯蒂娜

Description

红莉栖想要弄清楚楼下天王寺大叔的显像管电视对 “电话微波炉 (暂定)” 的影响.

选取显像管的任意一个平面, 一开始平面内有个 \(n\) 电子, 初始速度分别为 \(v_i\), 定义飘升系数为\(\sum\limits_{1 \le i < j \le n}|\mathbb{v_i} \times \mathbb{v_j}|^2\)

由于电视会遭到大叔不同程度的暴击, 电子的速度常常会发生变化. 也就是说, 有两种类型的操
作:

  • 1 p x y 将 \(\mathbb{v_p}\) 改为 \((x,y)\)

  • 2 l r 询问 $[l, r] $这段区间内的电子的飘升系数

这么简单的问题红莉栖当然能解决, 但是她需要一个人帮忙验证一下结果的正确性.

由于唯一帮得上忙的桶子去找菲利斯了, 于是只能拜托你来完成这个任务了.

答案对 \(20170927\) 取模即可.

Input Format

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

Output Format

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

测试点编号nm
1\(\le 100\)\(\le 100\)
2\(\le 500\)\(\le 500\)
3\(\le 1000\)\(\le 1000\)
4\(\le 5000\)\(\le 5000\)
5\(\le 10000\)\(\le 10000\)
6\(\le 50000\)\(\le 50000\)
7\(\le 100000\)\(\le 100000\)
8\(\le 500000\)\(\le 500000\)
9\(\le 1000000\)\(\le 1000000\)
10\(\le 1000000\)\(\le 1000000\)

Solution

注意这是叉乘。。一开始当点乘了。。

对区间\([l,r]\)的答案为

\[\sum_{l \le i < j \le r} (x_iy_j-x_jy_i)^2\]

\[=\sum_{i=l}^r x_i^2 \sum_{i=l}^r y_i^2- (\sum_{i=l}^rx_iy_i)^2\]

开三个树状数组就可以了

注意有点卡常,最好\(O(n)\)初始化


Code:

#include <cstdio>
#define ll long long
const int N=1000010;
const ll mod=20170927;
ll s[3][N],x[N],y[N];
int n,m;
void change(int id,int x,ll d)
{
    while(x<=n)
        (s[id][x]+=d)%=mod,x+=x&-x;
}
ll ask(int id,int x)
{
    ll sum=0;
    while(x)
        (sum+=s[id][x])%=mod,x-=x&-x;
    return (sum+mod)%mod;
}
ll query(int id,int l,int r)
{
    return ask(id,r)-ask(id,l);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",x+i,y+i);
        (s[0][i]+=x[i]*x[i]%mod+s[0][i-1])%=mod;
        (s[1][i]+=y[i]*y[i]%mod+s[1][i-1])%=mod;
        (s[2][i]+=x[i]*y[i]%mod+s[2][i-1])%=mod;
    }
    for(int i=n;i;i--)
    {
        s[0][i]-=s[0][i-(i&-i)];
        s[1][i]-=s[1][i-(i&-i)];
        s[2][i]-=s[2][i-(i&-i)];
    }
    ll x0,y0;
    for(int op,p,l,r,i=1;i<=m;i++)
    {
        scanf("%d",&op);
        if(op==1)
        {
            scanf("%d%lld%lld",&p,&x0,&y0);
            change(0,p,(x0*x0-x[p]*x[p])%mod);
            change(1,p,(y0*y0-y[p]*y[p])%mod);
            change(2,p,(x0*y0-x[p]*y[p])%mod);
            x[p]=x0,y[p]=y0;
        }
        else
        {
            scanf("%d%d",&l,&r);
            ll c1=query(0,l-1,r),c2=query(1,l-1,r),c3=query(2,l-1,r);
            printf("%lld\n",((c1*c2%mod-(c3*c3)%mod)%mod+mod)%mod);
        }
    }
    return 0;
}

2018.10.19

转载于:https://www.cnblogs.com/butterflydew/p/9816453.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值