J. 二进制与、平方和

https://codeforces.com/gym/104095/problem/J

分析操作一

1&0=0 ,0&1=0,ai<=qmi(2,24),说明每个数最多操作25次

维护区间或和,orsum & x== orsum 就不用递归下去了

势能线段树code

// Problem: J. 二进制与、平方和
// Contest: Codeforces - 2020 CCPC Henan Provincial Collegiate Programming Contest
// URL: https://codeforces.com/gym/104095/problem/J
// Memory Limit: 512 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long LL;
const int N=3e5+9;
const int mod=998244353;
int a[N];
template<class T>
constexpr T power(T a, LL b) {
    T res = 1;
    for (; b; b /= 2, a *= a) {
        if (b % 2) {
            res *= a;
        }
    }
    return res;
}
 
template<int P>
struct MInt {
    int x;
    constexpr MInt() : x{} {}
    constexpr MInt(LL x) : x{norm(x % getMod())} {}
    
    static int Mod;
    constexpr static int getMod() {
        if (P > 0) {
            return P;
        } else {
            return Mod;
        }
    }
    constexpr static void setMod(int Mod_) {
        Mod = Mod_;
    }
    constexpr int norm(int x) const {
        if (x < 0) {
            x += getMod();
        }
        if (x >= getMod()) {
            x -= getMod();
        }
        return x;
    }
    constexpr int val() const {
        return x;
    }
    explicit constexpr operator int() const {
        return x;
    }
    constexpr MInt operator-() const {
        MInt res;
        res.x = norm(getMod() - x);
        return res;
    }
    constexpr MInt inv() const {
        assert(x != 0);
        return power(*this, getMod() - 2);
    }
    constexpr MInt &operator*=(MInt rhs) & {
        x = 1LL * x * rhs.x % getMod();
        return *this;
    }
    constexpr MInt &operator+=(MInt rhs) & {
        x = norm(x + rhs.x);
        return *this;
    }
    constexpr MInt &operator-=(MInt rhs) & {
        x = norm(x - rhs.x);
        return *this;
    }
    constexpr MInt &operator/=(MInt rhs) & {
        return *this *= rhs.inv();
    }
    friend constexpr MInt operator*(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res *= rhs;
        return res;
    }
    friend constexpr MInt operator+(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res += rhs;
        return res;
    }
    friend constexpr MInt operator-(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res -= rhs;
        return res;
    }
    friend constexpr MInt operator/(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res /= rhs;
        return res;
    }
    friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
        LL v;
        is >> v;
        a = MInt(v);
        return is;
    }
    friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
        return os << a.val();
    }
    friend constexpr bool operator==(MInt lhs, MInt rhs) {
        return lhs.val() == rhs.val();
    }
    friend constexpr bool operator!=(MInt lhs, MInt rhs) {
        return lhs.val() != rhs.val();
    }
};
 
template<>
int MInt<0>::Mod =998244353;
 
template<int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();
 
constexpr int P =998244353;
using Z = MInt<P>;
 
const int mxn = 2e5 + 10;
struct SNSEG{
	#define ll long long 
	#define tl(id) (id<<1)
	#define tr(id) (id<<1|1)
	#define li inline
	struct node{
		Z pfval;
		int orsum;
	}seg[N<<2];
	#define pushup(id) seg[id].pfval=seg[tl(id)].pfval+seg[tr(id)].pfval, seg[id].orsum=seg[tl(id)].orsum|seg[tr(id)].orsum;
	li int inrange(int L,int R,int l,int r){return L>=l && R<=r;}
	li int outofrange(int L,int R,int l,int r){return L>r || l>R;}
	li void build(int id,int l,int r){
		if(l==r){
			seg[id].pfval=1ll*a[l]*a[l];
			// seg[id].val=a[l];
			seg[id].orsum=a[l];
			return;
		}
		int mid=(l+r)>>1;
		build(tl(id),l,mid);
		build(tr(id),mid+1,r);
		pushup(id);
	}
	li Z query(int id,int L,int R,int l,int r){
		if(inrange(L,R,l,r)){
			return seg[id].pfval;
		}else if(!outofrange(L,R,l,r)){
			int mid=(L+R)>>1;
			return query(tl(id),L,mid,l,r)+query(tr(id),mid+1,R,l,r);
		}else{
			return 0;
		}
	}
	li void modify(int id,int L,int R,int l,int r,int x){
		if(L==R){
			// seg[id].val&=x;
			seg[id].orsum&=x;//修改
			seg[id].pfval=1ll*seg[id].orsum*seg[id].orsum;
			return;
		}
		int mid=(L+R)>>1;
		if(mid>=l && (seg[tl(id)].orsum&x)!=(seg[tl(id)].orsum)){
			modify(tl(id),L,mid,l,r,x);
		}
		if(mid<r && (seg[tr(id)].orsum&x)!=(seg[tr(id)].orsum)){
			modify(tr(id),mid+1,R,l,r,x);
		}
		pushup(id);
	}
}t;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	t.build(1,1,n);
	int q;
	cin>>q;
	for(int i=1;i<=q;i++){
		int op;
		cin>>op;
		if(op==1){
			int l,r,x;
			cin>>l>>r>>x;
			t.modify(1,1,n,l,r,x);
		}else{
			int l,r;
			cin>>l>>r;
			cout<<t.query(1,1,n,l,r)<<'\n';		
		}
		// for(int i=1;i<=n;i++){
			// cout<<t.ask(1,1,n,i)<<" ";
		// }
		// cout<<'\n';
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是C语言编写的加、减、乘、除、阶乘、正弦、余弦、开平方、指数、对数运算,以及十进制数、二进制数、八进制数、十六进制之间的相互转换的示例代码。你可以根据需要进行修改和完善。 ```c #include <stdio.h> #include <math.h> void display_menu(); double add(double x, double y); double subtract(double x, double y); double multiply(double x, double y); double divide(double x, double y); int factorial(int n); double sine(double x); double cosine(double x); double square_root(double x); double exponent(double x); double logarithm(double x); void decimal_to_binary(int n); void decimal_to_octal(int n); void decimal_to_hexadecimal(int n); int main() { int choice; double x, y, result; int n; do { display_menu(); printf("Enter your choice: "); scanf("%d", &choice); switch (choice) { case 1: printf("Enter two numbers: "); scanf("%lf %lf", &x, &y); result = add(x, y); printf("Result: %lf\n", result); break; case 2: printf("Enter two numbers: "); scanf("%lf %lf", &x, &y); result = subtract(x, y); printf("Result: %lf\n", result); break; case 3: printf("Enter two numbers: "); scanf("%lf %lf", &x, &y); result = multiply(x, y); printf("Result: %lf\n", result); break; case 4: printf("Enter two numbers: "); scanf("%lf %lf", &x, &y); if (y == 0) { printf("Error: Division by zero!\n"); } else { result = divide(x, y); printf("Result: %lf\n", result); } break; case 5: printf("Enter an integer: "); scanf("%d", &n); if (n < 0) { printf("Error: Factorial of negative number does not exist!\n"); } else { result = factorial(n); printf("Result: %lf\n", result); } break; case 6: printf("Enter an angle in degrees: "); scanf("%lf", &x); result = sine(x); printf("Result: %lf\n", result); break; case 7: printf("Enter an angle in degrees: "); scanf("%lf", &x); result = cosine(x); printf("Result: %lf\n", result); break; case 8: printf("Enter a number: "); scanf("%lf", &x); if (x < 0) { printf("Error: Square root of negative number does not exist!\n"); } else { result = square_root(x); printf("Result: %lf\n", result); } break; case 9: printf("Enter a number: "); scanf("%lf", &x); result = exponent(x); printf("Result: %lf\n", result); break; case 10: printf("Enter a number: "); scanf("%lf", &x); if (x <= 0) { printf("Error: Logarithm of non-positive number does not exist!\n"); } else { result = logarithm(x); printf("Result: %lf\n", result); } break; case 11: printf("Enter a decimal number: "); scanf("%d", &n); decimal_to_binary(n); break; case 12: printf("Enter a decimal number: "); scanf("%d", &n); decimal_to_octal(n); break; case 13: printf("Enter a decimal number: "); scanf("%d", &n); decimal_to_hexadecimal(n); break; case 14: printf("Exiting the program...\n"); break; default: printf("Invalid choice!\n"); break; } printf("\n"); } while (choice != 14); return 0; } void display_menu() { printf("Math Operations Menu\n"); printf("--------------------\n"); printf("1. Add\n"); printf("2. Subtract\n"); printf("3. Multiply\n"); printf("4. Divide\n"); printf("5. Factorial\n"); printf("6. Sine\n"); printf("7. Cosine\n"); printf("8. Square Root\n"); printf("9. Exponent\n"); printf("10. Logarithm\n"); printf("11. Decimal to Binary\n"); printf("12. Decimal to Octal\n"); printf("13. Decimal to Hexadecimal\n"); printf("14. Exit\n"); } double add(double x, double y) { return x + y; } double subtract(double x, double y) { return x - y; } double multiply(double x, double y) { return x * y; } double divide(double x, double y) { return x / y; } int factorial(int n) { int result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; } double sine(double x) { double radians = x * M_PI / 180; return sin(radians); } double cosine(double x) { double radians = x * M_PI / 180; return cos(radians); } double square_root(double x) { return sqrt(x); } double exponent(double x) { return exp(x); } double logarithm(double x) { return log(x); } void decimal_to_binary(int n) { int binary[32]; int i = 0; while (n > 0) { binary[i] = n % 2; n /= 2; i++; } printf("Binary: "); for (int j = i - 1; j >= 0; j--) { printf("%d", binary[j]); } printf("\n"); } void decimal_to_octal(int n) { int octal[32]; int i = 0; while (n > 0) { octal[i] = n % 8; n /= 8; i++; } printf("Octal: "); for (int j = i - 1; j >= 0; j--) { printf("%d", octal[j]); } printf("\n"); } void decimal_to_hexadecimal(int n) { char hexadecimal[32]; int i = 0; while (n > 0) { int remainder = n % 16; if (remainder < 10) { hexadecimal[i] = remainder + '0'; } else { hexadecimal[i] = remainder - 10 + 'A'; } n /= 16; i++; } printf("Hexadecimal: "); for (int j = i - 1; j >= 0; j--) { printf("%c", hexadecimal[j]); } printf("\n"); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值