CCF-CSP 202012-5(80分暴力解法)

本文讲述了乔帝规划星际旅行中动力装置的操作与调整策略,包括动力增加、强化、转向和查询,涉及三维坐标计算及距离求解技巧。

问题描述

​​​​​​​

试题编号:202012-5
试题名称:星际旅行
时间限制:3.0s
内存限制:512.0MB
问题描述:

题目描述

乔帝要规划一次星际旅行,星际空间可以视为一个 3 维坐标系,乔帝有 n(n≤1,000,000,000) 个动力装置排成一行(下标从 1到 n )。

第 i 个动力装置可以让他的飞船 3 个维度的坐标分别增加 xi,yi,zi 。一开始这些动力装置的所有参数都是 0 。

在规划过程中,乔帝可能会对动力装置进行调整,也可能会对一些动力装置的动力进行评估。

具体来说,乔帝会进行 m(m≤40000) 次操作,每次操作可能是以下四种操作之一:

  • 动力增加:指定一个区间 [L,R] 和三个参数 a,b,c ,令区间内所有动力装置的3维坐标分别增加 a,b,c

  • 动力强化:指定一个区间 [L,R] 和一个参数 k ,令区间内所有动力装置的3维坐标分别乘 k

  • 动力转向:指定一个区间 [L,R] ,令区间内所有动力装置的 x,y,z 坐标分别变为原来的 y 坐标, z 坐标,x 坐标

  • 动力查询:指定一个区间 [L,R] ,询问如果使用区间内所有动力装置各一次能将乔帝送到离起点多远的地方(输出距离的平方除以1,000,000,007的余数)

输入格式

从标准输入读入数据。

第一行包含两个正整数 n,m。

接下来 m 行,每行用若干个空格分隔的整数表示一个操作。

每行的第一个整数表示这次进行的是哪一种操作,1,2,3,4分别表示动力增加、动力强化、动力转向、动力查询。

每行的接下来两个整数表示 L,R,含义如上面所述。

每行接下来若干个整数,根据操作类型确定,为a,b,c或k或空。

输出格式

输出到标准输出。

对于每个动力查询操作,输出一行,包含一个整数,表示查询的答案。

样例1输入

5 5
1 2 4 5 6 7
3 5 5
2 1 2 4
4 1 3
4 2 5

Data

样例1输出

2750
3960

Data

样例1解释

一共有5个动力装置。

对于第1个操作,令第2,3,4个动力装置的动力变为(5,6,7)。

对于第2个操作,令第5个动力装置转向,为(0,0,0)。

对于第3个操作,令第1,2个动力装置变为原来的4倍,第一个变为(0,0,0),第二个变为(20,24,28)。

对于第4个操作,是查询,送到离起点(0+20+5,0+24+6,0+28+7),距离的平方为2750。

对于第5个操作,也是查询,送到离起点(20+5+5+0,24+6+6+0,28+7+7+0),距离的平方为3960。

子任务

对于 20% 的数据,n,m≤1000;

对于另外 20% 的数据,n≤100000,且只包含第1,4种操作;

对于另外 20% 的数据,n≤100000,且只包含第1,2,4种操作;

对于另外 20% 的数据,n≤100000;

对于另外 20% 的数据,没有特殊性质。

所有输入的数字都在 [1,1000000000]范围内。

所有的数据中 1≤m≤40000。

所有的操作满足 1≤L≤R≤n。

//#include <bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<list>
#include<set>
#include<iomanip>
#include<cstring>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<cassert>
#include<sstream>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
typedef long long  ll;
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r)/2
#define over(i,s,t) for(register long long i=s;i<=t;++i)
#define lver(i,t,s) for(register long long i=t;i>=s;--i)
const int MAXN = 305;
const int INF = 0x3f3f3f3f;
const int N=5e4+7;
const int maxn=1e5+5;
const double EPS=1e-10;
const double Pi=3.1415926535897;
//inline double max(double a,double b){
//    return a>b?a:b;
//}
//inline double min(double a,double b){
//    return a<b?a:b;
//}
 
int xd[8] = {0, 1, 0, -1, 1, 1, -1, -1};
int yd[8] = {1, 0, -1, 0, -1, 1, -1, 1};
 
//void Fire(){
//    queue<node> p;
//    p.push({fx,fy,0});
//    memset(fire, -1, sizeof(fire));
//    fire[fx][fy]=0;
//    while(!p.empty()){
//        node temp=p.front();
//        p.pop();
//        for(int i=0;i<8;i++){
//            int x=temp.x+xd[i];
//            int y=temp.y+yd[i];
//            if(x<0||x>=n||y<0||y>=m||fire[x][y]!=-1){
//                continue;
//            }
//            fire[x][y]=temp.val+1;
//            p.push({x,y,temp.val+1});
//        }
//    }
//}
//int bfs(){
//    queue<node> p;
//    memset(vis, 0, sizeof(vis));
//    p.push({sx,sy,0});
//    while (!p.empty()) {
//        node temp=p.front();
//        vis[temp.x][temp.y]=1;
//        p.pop();
//        for(int i=0;i<4;i++){
//            int x=temp.x+xd[i];
//            int y=temp.y+yd[i];
//            if(x<0||x>=n||y<0||y>=m)  continue;
//            if(x==ex&&y==ey&&temp.val+1<=fire[x][y]) return temp.val+1;
//            if(vis[x][y]||temp.val+1>=fire[x][y]||a[x][y]=='#') continue;
//            p.push({x,y,temp.val+1});
//        }
//    }
//    return -1;
//}
int n,m;
struct Node{
    ll x=0;
    ll y=0;
    ll z=0;
}node[100000];
int main(){
    cin>>n>>m;
    ll x1,x2,x3;
    ll a,b,c;
    ll k;
    for(int i=0;i<m;i++){
        cin>>a;
        if(a==1){
            cin>>b>>c;
            cin>>x1>>x2>>x3;
            for(int j=b;j<=c;j++){
                node[j].x+=x1;
                node[j].y+=x2;
                node[j].z+=x3;
            }
            
        }
        else if(a==2){
            cin>>b>>c;
            cin>>k;
            for(int j=b;j<=c;j++){
                node[j].x*=k;
                node[j].x%=1000000007;
                node[j].y*=k;
                node[j].y%=1000000007;
                node[j].z*=k;
                node[j].z%=1000000007;
            }
        }
        else if(a==3){
            cin>>b>>c;
            int xx,yy,zz;
            for(int j=b;j<=c;j++){
                swap(node[j].x,node[j].z);
                swap(node[j].x,node[j].y);
            }
        }
        else if(a==4){
            cin>>b>>c;
            ll xx,yy,zz;
            for(int j=b;j<=c;j++){
                xx+=node[j].x;
                yy+=node[j].y;
                zz+=node[j].z;
            }
            cout<<((xx%1000000007)*(xx%1000000007)+(yy%1000000007)*(yy%1000000007)+(zz%1000000007)*(zz%1000000007))%1000000007<<endl;
            xx=0;
            yy=0;
            zz=0;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郭晋龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值