zoukankan      html  css  js  c++  java
  • CF1060H Sophisticated Device【构造】

    给定正整数 (d) 和质数 (p),用至多 (4999) 次模 (p) 意义下加法、(d) 次幂实现模 (p) 意义下乘法。

    (2le dle 10)(d<ple 10^9+9)


    考虑到 (xy=((x+y)^2-x^2-y^2)/2),也就是说在 (d=2) 的时候我们实现减法、乘常数就做完了,都可以用龟速乘实现。

    至于平方咋办呢?实际上可以构造 (a_0,a_1,cdots,a_d) 满足 (x^2=sum_{i=0}^da_i(x+i)^d=sum_{i=0}^dinom dix^{d-i}sum_{j=0}^dj^ia_j),用个 Gauss 消元解方程即可。

    操作次数大概 (O(dlog p)),常数不会算。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    int d, mod, A[12][12];
    void qmo(int &x){x += x >> 31 & mod;}
    int ksm(int a, int b){
    	int r = 1;
    	for(;b;b >>= 1, a = (LL)a * a % mod)
    		if(b & 1) r = (LL)r * a % mod;
    	return r;
    }
    void Gauss(int n){
    	for(int i = 0;i < n;++ i){
    		if(!A[i][i])
    			for(int j = i+1;j < n;++ j)
    				if(A[j][i]){swap(A[i], A[j]); break;}
    		int tmp = ksm(A[i][i], mod-2);
    		for(int j = i;j <= n;++ j) A[i][j] = (LL)A[i][j] * tmp % mod;
    		for(int j = 0;j < n;++ j) if(j != i)
    			for(int k = i+1;k <= n;++ k)
    				qmo(A[j][k] -= (LL)A[j][i] * A[i][k] % mod);
    	}
    }
    void mul(int a, int b, int c){
    	printf("+ 1001 1001 %d
    ", c);
    	printf("+ %d 1001 1002
    ", a);
    	for(;b;b >>= 1){
    		if(b & 1) printf("+ %d 1002 %d
    ", c, c);
    		puts("+ 1002 1002 1002");
    	}
    }
    void sub(int a, int b, int c){
    	mul(b, mod-1, 1003);
    	printf("+ %d 1003 %d
    ", a, c);
    }
    void pw2(int a, int b){
    	printf("+ 1001 1001 %d
    ", b);
    	printf("+ %d 1001 1004
    ", a);
    	for(int i = 0;i <= d;++ i){
    		puts("^ 1004 1005");
    		mul(1005, A[i][d+1], 1006);
    		printf("+ %d 1006 %d
    ", b, b);
    		if(i < d) puts("+ 1004 1007 1004");
    	}
    }
    int main(){
    	scanf("%d%d", &d, &mod);
    	for(int i = 0;i <= d;++ i)
    		for(int j = 0;j <= d;++ j)
    			A[i][j] = ksm(j, d-i);
    	A[2][d+1] = ksm(d*(d-1ll)>>1, mod-2);
    	Gauss(d+1);
    	for(int i = mod-1;i;i >>= 1){
    		if(i & 1) puts("+ 1000 1001 1001");
    		puts("+ 1000 1000 1000");
    	}
    	puts("+ 1 2 3");
    	pw2(1, 4); pw2(2, 5); pw2(3, 6);
    	puts("+ 4 5 7");
    	sub(6, 7, 8);
    	mul(8, mod+1>>1, 9);
    	puts("f 9");
    }
    
  • 相关阅读:
    详解 exception
    如何转换音频数据格式1
    解说一个简单的Win32程序
    java通过jxl.jar实现excel导入导出
    linux2.6.32在mini2440开发板上移植(8)之添加ADC驱动程序
    Hut 1997 Seven tombs
    python help dir stackoverflow docs google遇到python问题怎么样解决
    802.11n兼容a/b/g问题(Legacy mode,Mixed mode,Greenfield mode)
    gperf的使用
    ubuntu terminal 关闭防火墙
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/14839671.html
Copyright © 2011-2022 走看看