zoukankan      html  css  js  c++  java
  • HDU 6211 卡常数取模 预处理 数论

    求所有不超过1e9的 primitive Pythagorean triple中第2大的数取模$2^k$作为下标,对应a[i]数组的和。

    先上WIKI:https://en.wikipedia.org/wiki/Pythagorean_triple

    里面有通过欧几里得公式来得到有关毕达哥拉斯式子的一些性质。

    最后得到的一个关于互质的m,n变种的式子更加直观,因此枚举m,n,保证其合法。每次枚举n,筛掉和n有共同因子的m,范围是$sqrt{1e9}$。然后由于要求的是b,而且取模的都是2的幂指,因此可以先预处理所有$b%(2^{17})$的个数,最后再模$(2^k) $即可。

    但是用这个方法做这道题还会卡取模的常数,需要把取模换成$&(2^{17} - 1)$

    另一提,半夜两点和偶像在做同这题,人家是1A秒杀,而且代码很短,还是蛮高兴的,并不(。

    /** @Date    : 2017-09-17 23:49:14
      * @FileName: HDU 6211 青岛网络1006 欧几里得 数论.cpp
      * @Platform: Windows
      * @Author  : Lweleth (SoungEarlf@gmail.com)
      * @Link    : https://github.com/
      * @Version : $Id$
      */
    #include <bits/stdc++.h>
    #define LL long long
    #define PII pair<int ,int>
    #define MP(x, y) make_pair((x),(y))
    #define fi first
    #define se second
    #define PB(x) push_back((x))
    #define MMG(x) memset((x), -1,sizeof(x))
    #define MMF(x) memset((x),0,sizeof(x))
    #define MMI(x) memset((x), INF, sizeof(x))
    using namespace std;
    
    const int INF = 0x3f3f3f3f;
    const int N = 32000;
    const double eps = 1e-8;
    
    int pri[N];
    bool vis[N];
    int c = 0;
    int prime()
    {
    	MMF(vis);
    	for(int i = 2; i < N; i++)
    	{
    		if(!vis[i]) pri[c++] = i;
    		for(int j = 0; j < c && i * pri[j] < N; j++)
    		{
    			vis[i * pri[j]] = 1;
    			if(i % pri[j] == 0) break;
    		}
    	} 
    }
    LL coe[(1 << 17) + 20];
    LL s[(1 << 17) + 20];
    LL MA = (1LL<<17);
    int main()
    {
    	int T;
    	MMF(coe);
    	prime();
    	//cout << c << endl;
    	for(int i = 1; i * i <= 1000000000; i++)
    	{
    		MMF(vis);
    		int t = i;
    		for(int j = 0; j < c && pri[j] * pri[j] <= t; j++)
    		{
    			if(t % pri[j] == 0)
    			{
    				while(t % pri[j] == 0)
    					t /= pri[j];
    				for(int k = pri[j]; k <= N; k+=pri[j])
    					if(!vis[k]) vis[k] = 1;
    			}
    		}
    		if(t > 1)
    			for(int k = t; k < N; k+=t)
    					if(!vis[k]) vis[k] = 1;
    		for(int j = i + 1; j * j + i * i <= 1000000000; j++)
    		{
    			if(!vis[j]/*__gcd(i, j) == 1*/ && !(j&1 && i&1))
    			{
    				int a = 2 * i * j;
    				int b = j * j - i * i;
    				coe[max(a, b) & (MA - 1)]++;
    				//ans += s[max(a, b) % MA];
    			}
    		}					//cout << ans << endl;
    	}
    	scanf("%d", &T);
    	while(T--) 
    	{
    		int n;
    		scanf("%d", &n);
    		LL ans = 0;
    		int ma = (1 << n);
    		for(int i = 0; i < ma; i++)
    			scanf("%lld", s + i);
    		for(int i = 0; i < MA; i++)
    			ans += (LL)s[i & (ma - 1)] * coe[i];
    		printf("%lld
    ", ans);
    	}
        return 0;
    }
    /*
    5
    2
    0 0 0 1
    2
    1 0 0 0
    2
    1 1 1 1
    */
    //https://en.wikipedia.org/wiki/Pythagorean_triple
    
  • 相关阅读:
    系统进程查看 --- 微软官方出品
    Chrome 浏览器网页保存为PDF文件
    Chrome Google浏览器下载
    最强Android书 架构大剖析 作者网站
    腾讯暑期夏令营之旅
    轨迹记录App是怎样对定位轨迹进行过滤、优化和平滑处理的
    android-8~23 View.java
    android-23 View.java
    The server encountered an internal error that prevented it from fulfilling this request.
    Android Event
  • 原文地址:https://www.cnblogs.com/Yumesenya/p/7543151.html
Copyright © 2011-2022 走看看