0
点赞
收藏
分享

微信扫一扫

【洛谷主题库】P3987 我永远喜欢珂朵莉~

时光已翩然轻擦 2022-04-27 阅读 37
c++

这是截至 2022.1.9 我提交次数最多的题目之一。

咱们一步一步来。


我们随便打个暴力:

while(m--)
{
	int op,l,r,x;
	cin>>op>>l>>r;
	if(op==1)
	{
		cin>>x;
		for(int i=l;i<=r;i++)
		{
			if(a[i]%x==0) a[i]/=x;
		}
	}
	else
	{
		int s=0;
		for(int i=l;i<=r;i++)
		{
			s+=a[i];
		}
		cout<<s<<endl;
	}
}

「恭喜你获得了 12 pts 12\text{pts} 12pts 的好成绩。」


诶?为什么有一点 WA 了?
哦!
不开 long long 见祖宗!
int s=0;long long s=0;
「恭喜你获得了 15 pts 15\text{pts} 15pts 的好成绩。」


听取 TLE 声一片……试试 O2?
「恭喜你获得了 88 pts 88\text{pts} 88pts 的好成绩。」
质的飞跃。


还是有几点 T 了……
试试快读快出?
试试就逝世。
「恭喜你获得了 88 pts 88\text{pts} 88pts 的好成绩。」


啊这……
等下!
当操作一的 x = 1 x=1 x=1 时, a i 1 = a i \frac{a_i}{1}=a_i 1ai=ai,不需要做!

if(x==1) continue;

「恭喜你获得了 91 pts 91\text{pts} 91pts 的好成绩。」


让我看看 #1 是什么情况……
刚才是 x = 1 x=1 x=1,那 x = 2 x=2 x=2 呢……
诶它是 2 2 2 的次幂,可以位运算诶!
卡常大法……对!再循环展开!
「恭喜你获得了 100 pts 100\text{pts} 100pts 的好成绩。」
氢氧根离子。
AC Code(+O2):

#include<bits/stdc++.h>
using namespace std;

int n,m,a[100005],i;//i 放在这是避免多次定义
long long s;

int read()//快读
{
    int x=0,f=1;
    char ch=getchar();
    while(!isdigit(ch))
	{
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(isdigit(ch))
	{
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

void write(long long x)//快出
{
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

int main()
{
	n=read();
	m=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
	}
	while(m--)
	{
		int op=read(),l=read(),r=read(),x;
		if(op==1)//操作一
		{
			x=read();
			if(x==1) continue;//x=1 的特判
			if(x==2)//x=2 的特判
			{
				for(i=l;i<=r-5;i+=6)
				{//循环展开
					!(a[i]&1)?a[i]>>=1:1;
					!(a[i+1]&1)?a[i+1]>>=1:1;
					!(a[i+2]&1)?a[i+2]>>=1:1;
					!(a[i+3]&1)?a[i+3]>>=1:1;
					!(a[i+4]&1)?a[i+4]>>=1:1;
					!(a[i+5]&1)?a[i+5]>>=1:1;
				}
				while(r-i+1)
				{//当不够展开时的补充
					!(a[i]%x)?a[i]/=x:1;
					i++;
				}
			}
			else
			{
				for(i=l;i<=r-5;i+=6)
				{//循环展开
					!(a[i]%x)?a[i]/=x:1;
					!(a[i+1]%x)?a[i+1]/=x:1;
					!(a[i+2]%x)?a[i+2]/=x:1;
					!(a[i+3]%x)?a[i+3]/=x:1;
					!(a[i+4]%x)?a[i+4]/=x:1;
					!(a[i+5]%x)?a[i+5]/=x:1;
				}
				while(r-i+1)
				{
					!(a[i]%x)?a[i]/=x:1;
					i++;
				}
			}
		}
		else//操作二
		{
			s=0;
			for(i=l;i<=r-5;i+=6)
			{//循环展开
				s+=a[i]+a[i+1]+a[i+2]+a[i+3]+a[i+4]+a[i+5];
			}
			while(i<=r)
			{
				s+=a[i++];
			}
			write(s);
			puts("");
		}
	}
 	return 0;
}
举报

相关推荐

0 条评论